520 likes | 789 Views
Java Web 项目开发培训. Ssh2 + Jbpm4 + Oracle 10g 2010.5. 程序开发规范. SSH2 框架整合. JBPM4 基本概念. OA 项目架构. 程序开发规范. 参见附件 《 编码开发规范 》 及 《 开发管理工作流程 》. SSH2 框架整合 ( 配置文件 ). Eclipse (galileo) struts2 hibernate3 spring2 Dynamic web project Web.xml Struts.xml Hibernate.cfg.xml applicationContext.xml.
E N D
Java Web项目开发培训 Ssh2 + Jbpm4 + Oracle 10g 2010.5
程序开发规范 • SSH2 框架整合 • JBPM4基本概念 • OA项目架构
程序开发规范 • 参见附件《编码开发规范》及《开发管理工作流程》
SSH2 框架整合(配置文件) • Eclipse (galileo) struts2 hibernate3 spring2 • Dynamicwebproject • Web.xml • Struts.xml • Hibernate.cfg.xml • applicationContext.xml
Web.xml • 1,定义filter拦截用户请求 • <filter> • <filter-name>struts2</filter-name> • <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> • </filter> • 2,创建Spring容器 • <listener> • <listener-class> • org.springframework.web.context.ContextLoaderListener • </listener-class> • </listener>
Structs.xml • <action name="actionWork" class="workAction"> • <result>/view/viewWork.jsp</result> • <result name="draft">/view/viewWorkDraft.jsp</result> • <result name="end">/view/viewWorkEnd.jsp</result> • <result name="new">/comment/newWork.jsp</result> • <result name="work">/view/actionWork.jsp</result> • <result name="finish">/finish.jsp</result> • <result name="restrict">/error.jsp</result> • <result name="tasklist">/view/viewTasklist.jsp</result> • <result name="nologin" type="redirect">/index1.jsp</result> • </action>
Hibernate.cfg.xml • <session-factory> • <property name="dialect"> • org.hibernate.dialect.OracleDialect • </property> • <property name="connection.driver_class"> • oracle.jdbc.driver.OracleDriver • </property> • <property name="connection.username">oa</property> • <property name="connection.password">aa2010</property> • <property name="connection.url"> • jdbc:oracle:thin:@172.168.0.1:1521:orcl • </property> • <property name="hibernate.c3p0.max_size">20</property> • <property name="hibernate.c3p0.min_size">1</property> • <property name="hibernate.c3p0.timeout">0</property> • <property name="hibernate.c3p0.max_statements">50</property> • <!-- <property name="hbm2ddl.auto">none</property>--> • <property name="show_sql">true</property> • <mapping resource="work/model/WorkComments.hbm.xml" />
applicationContext.xml (1) • <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> • <property name="configLocation" value="classpath:jbpm.hibernate.cfg.xml" /> • <property name="dataSource" ref="dataSource" /> • </bean> • <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> • <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> • <property name="url" value="jdbc:oracle:thin:@172.168.0.1:1521:orcl" /> • <property name="username" value="oa" /> • <property name="password" value="oa2010" /> • </bean>
applicationContext.xml (2) • <bean id="daoTemplate" abstract="true" lazy-init="true"> • <property name="sessionFactory" ref="sessionFactory" /> • </bean> • <bean id="workAction" class="work.service.WorkAction" singleton="false"> • <property name="processOP" ref="processDao"/> • <property name="userOP" ref="userDao"/> • <property name="processEngine" ref="processEngine" /> • <property name="workOP" ref="workDao"/> • </bean>
SSH2 框架整合(Model) • POJO持久化对象,hibernate低侵入式的设计,虽然没有太多的要求,但建议遵守以下规则: • 1,无参构造器 • 2,提供一个标识属性(映射主健) • 3,每个属性setter,getter • 4,重写equals() hashcode() • public class Office implements Serializable { • private static final long serialVersionUID = -1653454005033632771L; • private String office_id; • private String office_code; • //D:部门,C:公司,S:体系,T:体系中心,G:总部中心,H:集团总部,E:体系中心部门,B:集团总部中心部门 • private String office_type; • private String inputperson; • private int is_dept=0; • private int is_internal=0;
SSH2 框架整合(Model) • 配置文件office.hbm.xml • <class name="Office" • table="SB_OFFICE" schema="oa" lazy="false"> • <id • name="office_id" type="java.lang.String" column="office_id" length="32"> • <generator class="uuid" /> • </id> • <property name="office_code" type="java.lang.String" length="32" • column="office_code" not-null="false"/> • <property name="office_type" type="java.lang.String" • <property name="is_dept" type="java.lang.Integer" • column="is_dept" not-null="false"/> • … • <many-to-one name="superior_office" column="superior_office_id" class="Office" lazy="false" /> • <many-to-one name="manager" column="manager_id" class="Person" lazy="false" /> • </class>
SSH2 框架整合(Model) • 持久化对象状态 • 瞬态 由new操作创建,垃圾回收机制管理 • 持久化 在数据库中有对应的记录,并拥有一个持久化标志符(自动保存到数据库) • 脱管 曾经处于持久化但与之关联的session关闭 • 改变持久化对象状态的方法save,update,get
StrutsAction 业务控制器 • Action继承ActionSupport • 允许一个action内包含多个控制处理逻辑 • public class LoginAction extends ActionSupport{ • @Override • public String execute() throws Exception { • ActionContext ctx = ActionContext.getContext(); • HttpServletRequest request = (HttpServletRequest)ctx.get(ServletActionContext.HTTP_REQUEST); • HttpServletResponse response = (HttpServletResponse)ctx.get(ServletActionContext.HTTP_RESPONSE); • request.setAttribute("menuArrayList", menuArrayList); • 。。。 • Return SUCCESS
StrutsAction 业务控制器 • Action处理用户请求结束后返回一个普通字符串----逻辑视图名,必须在struts.xml文件完成逻辑视图和物理视图资源的映射才可让系统转到实际的视图资源 • <result name="tasklist">/view/viewTasklist.jsp</result> • <result name="nologin" type="redirect">/index1.jsp</result> • struts2使用多种视图技术,jsp,redirect,stream…
Struts国际化 • 全局资源文件,包资源文件定义与加载, Native_2ascii工具 • #button message • filepage.button.ok=OK • filepage.button.reset=Reset • filepage.button.cancel=Cancel • filepage.button.search=Search • filepage.button.delete=Delete • #button message • filepage.button.ok=\u786e\u5b9a • filepage.button.reset=\u91cd\u7f6e • filepage.button.cancel=\u53d6\u6d88 • filepage.button.search=\u641c\u7d22 • filepage.button.delete=\u5220\u9664\u6240\u9009 • 访问国际化消息(jsp,action…)
DAO设计模式 • 目前可能极少有j2ee 应用会直接以jdbc方式进行持久层访问 • DAO模式是一种标准的j2ee设计模式,核心思想:所有的数据库访问都通过dao组件完成,组件封装了数据库的增,删,改等原子操作,业务逻辑组件依赖dao提供的原子操作
DAO设计模式 • 轻量级javaEE架构以sping Ioc为核心,向上管理表现层的action向下管理业务逻辑层组件,同时负责管理dao对象 • Spring提供多种数据库访问技术的dao支持, • Hibernate: • HibernateDaoSupport • HibernateTemplate • HibernateCallback
DAO设计模式 • public interface ProcessDao { • ProcessDefine get(String processid); • Serializable save(ProcessDefine process); • void update(ProcessDefine process); • void update(String processid,ProcessDefine process); • …. • } • public class ProcessDaoHibernate extends HibernateDaoSupport implements ProcessDao
DAO设计模式 • 管理hibernate的sessionFactory • 持久层访问,单个数据库映射关系的内存镜像 • Spring Ioc容器提供声明式配置sessionFactory实例,还可以注入数据源引用 • <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> • <property name="configLocation" value="classpath:jbpm.hibernate.cfg.xml" /> • <property name="dataSource" ref="dataSource" /> • </bean>
DAO设计模式 • hibernateTemplate提供持久层访问模板化,无须实现特定接口,引用sessionFactory就可执行持久化操作 • 对于web应用启动时自动创建applicationContext,可采用依赖注入实现sessionFactory和dao的解耦 • public class WorkDaoHibernate extends HibernateDaoSupport implements WorkDao { • @Override • public long countWorks(String usrId,int actived) { • 。。。 • return (Long)getHibernateTemplate().find("select count(*) from Work where actived=?",actived) • .get(0); • }
DAO设计模式 • hibernateTemplate提供很多实用方法完成基本操作,比如增加,删除,修改,查询等,spring2.x更增加了对命名sql查询的支持,分页的支持 • Void delete(Object entity) • Find(String queryString) • findByNamedQuery(String queryName) • Get(Class entityClass,Serialized id) • Save(Object entity) • Update(Object entity) • setMaxResults(int maxResults)
DAO设计模式 • hibernateTemplate还提供一种更加灵活的方式来操作数据库: • Objectexecute(hibernateCallback action) • List executeFind(hibernateCallback action) • 以上都需要一个hibernateCallback实例,该实例可在任何有效的hibernate数据访问中使用 • hibernateCallback是个接口,程序开发中必须实现接口里的doInHibernate方法
DAO设计模式 • final String hsql=new String("from Work where usr_id=? and actived=? order by create_date desc"); • result=(ArrayList<PersonPosition>)getHibernateTemplate().executeFind(new HibernateCallback(){ • public Object doInHibernate(Session session) throws HibernateException,SQLException{ • List result=session.createQuery(hsql).setParameter(0, usrId).setParameter(1, actived) • .setFirstResult(pageSize*(currentPageNo-1)).setMaxResults(pageSize).list(); • return result; • } • });
DAO设计模式 • final String wkid=work.getWorkid(); • final int read=work.getUnread(); • getHibernateTemplate().execute(new HibernateCallback(){ • public Object doInHibernate(Session session) throws HibernateException,SQLException{ • return session.createQuery("update WorkProcess set unread=? where work.workid=? and assigneeid=?") • .setParameter(0, read) • .setParameter(1, wkid) • .setParameter(2, usrId) • .executeUpdate(); • } • });
Hibernate使用 • 单向N-1关联 • private Office superior_office; • <many-to-one name="superior_office" column="superior_office_id" class="Office" lazy="false" /> • 批量插入与更新,数据量过大时抛出内存溢出异常,需要手工清空缓存,效果不好 • DML批量更新与删除 • Update | delete from <Classname> where … • session.createQuery("delete WorkComments where work.workid in (select workid from Work where bsid=?)") • .setParameter(0, attendId).executeUpdate();
IoC容器 • javaEE所需各种组件目前都已经出现,从mvc控制器组件到业务逻辑组件以及持久层dao组件,但并未直接耦合,组件与组件之间面向接口编程,所以还需要利用spring的IoC容器将它们组合在一起 • public class WorkAction extends ActionSupport { • private ProcessDao processOP; • private WorkDao workOP; • private ProcessEngine processEngine; • private UserDao userOP; • }
IoC容器 • 当用户发送一个请求后,该请求将被struts2核心控制器拦截核心控制器调用actionaction调用业务逻辑组件业务逻辑组件调用dao组件dao组件调用sessionFactory,Hibernate服务等,当整个过程完成后核心控制器就得到了请求被处理的结果,从而根据该结果选择合适的视图资源来生成响应这就完成了一个请求/响应的全过程。
声明式事务 • 上面配置文件中部署了控制器组件,业务逻辑组件,dao组件,几乎可以形成一个完整的javaEE应用,但有一个小小的问题:事务控制。系统中没有任何事务逻辑,没有事务的应用是不可想象的。 • Spring的事务机制非常优秀,允许我们在开发过程中无须理会任何事务逻辑,等到应用完成后使用声明式事务来进行统一的事务管理。 • 1,针对不同事务策略配置事务管理器 • 2,使用<tx:advice…/>配置事务切面bean, • 3,在<aop:config../>使用<aop:advisor…/>配置事务代理。
JavaServerPage • JSP页面内容由2部分组成 • 静态部分:标准的html标签,静态的页面内容,与静态html页面相同 • 动态部分:受java程序控制的内容,这些内容程序自动生成 • 事实上每个jsp就是一个servlet实例 • Jsp表达式 • <%=表达式 %> • Jsp脚本 • <% • For(int i=0;i<10;i++){ • } • %> • <!-- 上面的循环控制<tr>标签的循环--> • <tr><td>value:</td> • <td><%=i%></td> • </tr> • <%}%>
Web应用的4个对象 • 几乎所有的web服务器都提供4个类似map的结构 • Application 对于整个应用有效 • Session 仅对一次会话有效 • Request 仅对本次请求有效 • Page 仅对当前页面有效 • Jsp中的application,session,request,pageContext4个内置对象分别用于操作以上范围的数据
EL表达式 • EL表达式既可以和jsp结合也可以和jstl结合使用,从而大量地减少jsp页面中的java代码增强程序可读性 • 作为java web开发人员需要熟悉el表达式的书写语法,熟练运用el的隐含对象 • EL提供. [] 运算符存取对象 • ${sessionScope.user.name} • 算术运算符 +- * /% • 关系运算符 == (eq) != (ne) <(lt) >(gt) >= <= • ${param.password1==param.password2} • 逻辑运算符 && || ! And or not
EL隐含对象 • pageContext 表示jsp页面上下文 • pageScopepage范围所有的属性名称及对应的值 • requestScope request范围所有的属性名称及对应的值 • sessionScope session范围所有的属性名称及对应的值 • applicationScope application范围所有的属性名称及对应的值
JSTL标签技术 • jsp标准标签库功能 • 配合EL表达式,显示表达式结果,设置与得到jsp页面中的变量或属性值 • 流程控制 • <c:if test=“条件表达式”> • </c:if> • <c:choose> </c:when> </c:otherwise> • </c:choose>
Struts2对表达式的支持 • 支持ELjsp2.0标准表达式语言 • OGNL 一种可以方便的操作对象属性的开源表达式语言,Struts2默认的表达式语言 • OGNL上下文中的元素 • request 包含当前HttpServletRequest的属性的map #request.username 相当于request.getAttribute(“username”) • session 包含当前HttpSession的属性的map • #session.username相当于session.getAttribute(“username”) • attr 用于按照requestsessionapplication顺序访问
Struts2标签,OGNL与集合 • <s:set var="vmofficetype" value="#{'D':'分公司部门','C':'公司','S':'体系','T':'体系中心','E':'体系中心部门','G':'总部中心','H':'集团总部','B':'集团总部中心部门'}" scope="page"/> • <s:select list="#attr.vmofficetype" name="office.office_type" /> • <s:select name="office.superior_office.office_id" list="#request.officeArrayList" • listKey="office_id" listValue="office_native_name" headerKey="" headerValue="==请选择=="/>
jQuery • Javascript工具包 • 重点放在从html页面里获取元素并对其进行操作 • 把确保代码能够跨越所有主要的浏览器以一致性的方式工作 • $(document).ready(function(){ • $(“table tr:nth-child(even)”).addClass(“even”) • } • jQuery选择器的威力 • var or=$("select[id=positionid]"); • $("#officeid").change(function(){}
Ajax • 可以说近年来没有一项比ajax更有力的改变web的景观,无需重新加载页面而向服务器发起异步请求的这种能力,已经启用一整套全新的用户交互方式并使用富因特网应用而成为可能。 • $.getJSON("actionPositionJson?nocache="+new Date().getTime()+"&office_id="+myofficeid,{"resultType":"json"},function(data,textStatus){ • var myOptions=""; • for(var i=0;i<data.length;i++){ • myOptions=myOptions+'<option value="'+data[i][0]+'" selected="selected">'+data[i][1]+'</option>'; • } • $("#positionid").html(myOptions); • });
JBPM4基本概念 • jBPM是一个可扩展、灵活的流程引擎, 它可以运行在独立的服务器上或者嵌入任何Java应用中。 • 一个流程定义是对过程的步骤的描述。 • 流程实例代表着流程定义的特殊执行例子 • 在jBPM内部通过各种服务相互作用。 服务接口可以从ProcessEngine中获得, 它是从Configuration构建的。 • 部署流程 • 启动一个新的流程实例
jDPL流程语言 • <?xml version="1.0" encoding="UTF-8"?> • <process name="Purchase order" xmlns="http://jbpm.org/4.3/jpdl"> • <start> • <transition to="Verify supplier" /> • </start> • <state name="Verify supplier"> • <transition name="Supplier ok" to="Check supplier data" /> <transition name="Supplier not ok" to="Error" /> </state> • <decision name="Check supplier data"> • <transition name="nok" to="Error" /> • <transition name="ok" to="Completed" /> • </decision> • <end name="Completed" /> • <end name="Error" /> • </process>
控制流程Activities活动 • start启动 • 说明一个流程的实例从哪里开始。 在一个流程里必须有一个开始节点。 一个流程必须至少拥有一个开始节点。 开始节点必须有一个向外的流向,这个流向会在流程启动的时候执行。
控制流程Activities活动 • decision决定节点在多个选择中选择一条路径。也可以当做是一个决定。 一个决定活动拥有很多个向外的转移。当一个流向到达一个决定活动时, 会自动执行并决定交给哪个向外的转移。
控制流程Activities活动 • <process name="DecisionExpression" xmlns="http://jbpm.org/4.3/jpdl"> • <start > • <transition to="evaluate document"/> • </start> • <decision name="evaluate document" expr="#{content}"> • <transition name="good"to="submit document" /> • <transition name="bad"to="try again" /> • <transition name="ugly"to="give up" /> • </decision> • <state name="submit document" /> • <state name="try again" /> • <state name="give up" /> • </process>
控制流程Activities活动 • concurrency并发使用fork和join活动, 可以模拟流向(executions)的汇合。
控制流程Activities活动 • end结束默认情况下,结束活动会终结已完成流程处理实例。 因此在流程处理实例中, 仍然在活动的多个并发(concurrent)流向(concurrent) 也会结束。
控制流程Activities活动 • Task在任务组件中,为一个人创建一个任务。 • 一个简单的任务会被分配给一个指定的用户 • <process name="TaskAssignee"> • <start> <transition to="review" /> • </start> • <task name="review" assignee="#{order.owner}"> • <transition to="wait" /> • </task> • <state name="wait" /> • </process>
控制流程Activities活动 • 当一个新流程实例会被创建, 把order作为一个流程变量分配给它。 • Map<String, Object> variables = new HashMap<String, Object>(); variables.put("order", new Order("johndoe")); ProcessInstance processInstance = executionService .startProcessInstanceByKey("TaskAssignee", variables); 然后johndoe的任务列表可以像下面这样获得。 • List<Task> taskList = taskService.findPersonalTasks("johndoe"); 注意也可以使用纯文本, assignee="johndoe"。 在这里,任务会被分配给johndoe。
控制流程Activities活动 • 任务变量 • 任务可以读取,更新流程变量。 稍后任务可以选择定义任务本地流程变量。 任务变量是任务表单的一个很重要的部分。 任务表单显示来自任务和流程实例的数据。 然后从用户一侧录入的数据会转换成设置的任务变量。 • 获得任务变量就像这样: • List<Task> taskList = taskService.findPersonalTasks("johndoe"); Task task = taskList.get(0); long taskDbid = task.getDbid(); Set<String> variableNames = taskService.getVariableNames(taskDbid); Map<String, Object> variables = taskService.getVariables(taskDbid, variableNames); 设置任务变量就像这样: • variables = new HashMap<String, Object>(); variables.put("category", "small"); variables.put("lires", 923874893); taskService.setVariables(taskDbid, variables);
自动活动 • java任务。流程处理的流向会执行 这个活动配置的方法。 • <start > <transition to="greet" /> </start> • <java name="greet" class="org.jbpm.examples.java.JohnDoe" method="hello" var="answer" > • <field name="state"><string value="fine"/> • </field> • <arg><string value="Hi, how are you?"/></arg> • <transition to="shake hand" /> • </java> • <java name="shake hand" expr="#{hand}" method="shake" var="hand" > <arg><object expr="#{joesmoe.handshakes.force}"/></arg> <arg><object expr="#{joesmoe.handshakes.duration}"/></arg> <transition to="wait" /> • </java>
OA架构 • OA系统应该是协同办公系统,在统一的企业信息平台上实现行政、人事、财务、业务、客户、决策等处理,使所有员工都在统一且个性化的信息门户中一起工作,摆脱时间和地域的限制,实现协同工作与知识管理。