1、SCCE 2010课程体系介绍,第5章 jBPM+SSH,回顾,掌握jBPM的Web工程的搭建 jBPM的配置文件 hibernatge.cfg.xml jbpm.cfg.xml jbpm.mail.templates.xml jBPM的JAR包 jbpm-jpdl.jar jbpm-identity.jar 掌握jBPM整合Struts的步骤及应用,本章内容,jPBM和SSH的整合方式 jBPM和SSH的整合步骤 工作流审批过程中邮件通知的使用方法 流程进度图的实现,本章目标,熟悉jBPM整合SSH的环境 掌握jBPM整合SSH的步骤 掌握工作流审批过程中邮件通知的用法 掌握在Web应用中使
2、用流程图和高亮显示流程节点的方法,1. jBPM整合SSH,1.1 需求分析 具体需求如下 公司员工登录系统,填写请假单 提交请假单后,单据流向员工部门主管处进行审批 如果部门主管审批不通过,则流程结束 如果部门主管审批通过,则需要进行请假天数的判断 如果请假天数小于5天,单据直接由人事部门处理 如果请假天数大于5天,则请假单还需要总经理审批,只有总经理审批通过后才交由人事部门处理 如果总经理审批不通过,则流程也将结束,1.2 创建业务数据库,请假流程的业务表数据模型,1.3 搭建支持jBPM的SSH工程,SSH整合jBPM配置文件的Hibernate.cfg.xml,搭建支持jBPM的SSH
3、工程,添加jbpm-jpdl.jar和jbpm-identity.jar包,2. 开发流程,2.1 创建流程图 根据请假需求,创建请假流程图,2.2 分配任务,给请假申请人分配部门主管参与者,public class ManagerAssignment implements AssignmentHandlerpublic void assign(Assignable arg0, ExecutionContext arg1) throws Exception /从流程变量中获得申请人的部门主管String leaveEmp = arg1.getContextInstance().getVaria
4、ble(“manager“).toString();arg0.setActorId(leaveEmp); ,设置部门主管参与者,分配任务,给请假申请人分配总经理参与者,public class BossAssignment implements AssignmentHandler public void assign(Assignable arg0, ExecutionContext arg1) throws Exception /从JbpmContext中获得SessionSession session = arg1.getJbpmContext().getSession();String
5、hql = “select model.emp from Depart as model where model.depName = 管理部“;/总经理用管理部的负责人代替Emp emp = (Emp)session.createQuery(hql).uniqueResult();System.out.println(“name:“+emp.getEmpName();arg0.setActorId(emp.getEmpName(); ,设置总经理参与者,分配任务,给请假申请人分配人事参与者,public class PersonnelAssignment implements Assignme
6、ntHandler public void assign(Assignable arg0, ExecutionContext arg1) throws Exception /从JbpmContext中获得SessionSession session = arg1.getJbpmContext().getSession();String hql = “select model.emp from Depart as model where model.depName = 人事部“;/获得人事部门的负责人Emp emp = (Emp)session.createQuery(hql).uniqueRe
7、sult();System.out.println(“name:“+emp.getEmpName();arg0.setActorId(emp.getEmpName(); ,设置人事参与者,2.3 流程动作,审批不通过或者人事处理完成之后通过发送邮件通知申请人 使用Spring的方式向申请人发送邮件通知,public class LeaveNotifyAction implements ActionHandler public void execute(ExecutionContext arg0) throws Exception ApplicationContext ctx = new Cla
8、ssPathXmlApplicationContext(“applicationContext_*.xml“); MailSender sender = (MailSender)ctx.getBean(“mailSender“);/从容器中获取MailSender实例 SimpleMailMessage message = new SimpleMailMessage();/创建SimpleMailMessage对象 message.setTo(“SCCE_TO“);/设置收信人地址 message.setFrom(“SCCE_FROM“); /设置发信人地址boolean flag = fal
9、se; ContextInstance ci = arg0.getContextInstance();/获得流程上下文对象 String name = (String)ci.getVariable(“name“);/获得单据类型 String user = (String)ci.getVariable(“emp“);/获得申请人 String approveResult = (String)ci.getVariable(“approveResult“);/获得请假申请是否通过if(“1“.equals(approveResult)flag = true;if(flag) message.set
10、Subject(“审批结果“);/设置主题 message.setText(user+“,您的“+name+“申请审批已经通过“);/设置内容else message.setSubject(“审批结果“);/设置主题 message.setText(user+“,您的“+name+“申请审批没有通过“);/设置内容arg0.getToken().signal(); sender.send(message);/发送邮件 ,流程动作,要实现邮件的发送,则还需要在Spring的配置文件中进行配置,true2500 **,1、开发持久层 按照SSH的方式开发持久层,其BaseDAO类及其配置如下:,p
11、ublic class BaseDAO extends HibernateDaoSupport /实体对象全路径名称,包括包名private String poName = “;public List getObjects()List poList = null;try String hql = “from “ + poName;poList = this.getHibernateTemplate().find(hql); catch (Exception e) e.printStackTrace();return poList;public void setPoName(String poN
12、ame) this.poName = poName; ,3. jBPM + SSH整合步骤,对poName设置注入,查询所有记录,其他方法省略,jBPM + SSH整合步骤,具体业务的DAO实现该BaseDAO即可 ,DAO的配置如下:,com.hr.g3.persist.Emp,把SessionFactory注入给BaseDAO的HibernateDaoSupport,把具体的实体对象注入给具体DAO,2. 开发业务逻辑层 业务表的业务逻辑类只需要封装业务DAO,而流程的业务逻辑类(WorkFlowHandlerImpl )如下 :流程业务逻辑配置文件如下:,jBPM + SSH整合步骤,/
13、获取系统已定义的所有流程名称列表 public List queryAllProcessDefinition()JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext();return jbpmContext.getGraphSession().findLatestProcessDefinitions(); /搜索流转到用户activeId的所有待审核的流程实例 public List queryCurrentProcessInstances(String activeId)List busines
14、sIds = new ArrayList();JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext();List tis = jbpmContext.getTaskMgmtSession().findTaskInstances(activeId);for(TaskInstance ti:tis)if (ti.isSignalling() /如果这个任务处于正在等待被完成的状态 businessIds.add(ti.getProcessInstance().getKey();return busin
15、essIds; /其他方法省略,/其他方法省略,jBPM + SSH整合步骤,3.开发表示层 查看所有定义流程Action,public class FlowAction extends DispatchAction private WorkFlowHandler workFlowHandler; /查看所有定义流程public ActionForward queryAllFlow(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exce
16、ption ActionForward forward = new ActionForward();List pdList = workFlowHandler.queryAllProcessDefinition();request.setAttribute(“pdList“, pdList);forward = mapping.findForward(“queryAllFlow“);return forward;public void setWorkFlowHandler(WorkFlowHandler workFlowHandler) this.workFlowHandler = workF
17、lowHandler; /其他方法省略,jBPM + SSH整合步骤,4.通过页面实现流程流转 人事部门员工登录后可以查询流程和部署流程,ID号 流程名称 流程版本 操作 $flow.id $flow.name $flow.version 删除流程/其他页面省略,5.页面效果 用户登录 查询流程和部署流程 查询请假单 申请请假单 部门负责人审批请假单 邮件通知,jBPM + SSH整合步骤,jBPM + SSH整合步骤,申请人在请假的过程中,如果需要了解请假单的状态,可通过流程图定位文件gpd.xml展示流程进度图 流程定位文件和流程图文件保存jBPM数据库中,因此可以根据这两个文件获得流程进
18、度图,jBPM + SSH整合步骤,通过Servlet(ProcessImageServlet)获得流程图,protected void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException String pdId = request.getParameter(“pdId“);/获得流程定义ID JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext(
19、); try /通过流程ID,获得流程定义ProcessDefinition pd = jbpmContext.getGraphSession().loadProcessDefinition(new Long(pdId);/获得流程图片保存在数据库的二进制信息byte bytes = pd.getFileDefinition().getBytes(“processimage.jpg“);OutputStream output = response.getOutputStream(); /图片输出output.write(bytes);output.flush();output.close();
20、 catch (Exception e) e.printStackTrace();finallyjbpmContext.close(); ,jBPM + SSH整合步骤,web.xml中配置该Servlet,ProcessImageServletcom.hr.g3.servlet.ProcessImageServletProcessImageServlet/processImageServlet ,jBPM + SSH整合步骤,http:/localhost:8989/JBPMT_TP6_01/processImageServlet?pdId=2,获得ID为2的流程图,jBPM + SSH整合
21、步骤,通过gpd.xml可以定位节点位置,高亮显示审批节点。请假单gpd.xml如下, 。,节点名称、宽、高及坐标,省略其他节点坐标,jBPM + SSH整合步骤,高亮现象流程节点的Action,public ActionForward processImage(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) throws IOException PrintWriter out = response.getWriter();ActionForward
22、 forward = new ActionForward(); String tokenId = request.getParameter(“tokenId“); /获得令牌IDJbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext(); try Token token = jbpmContext.getToken(new Long(tokenId); /获得当前令牌String nodeName = token.getNode().getName(); /获得当前节点ProcessDefiniti
23、on pd = token.getProcessInstance().getProcessDefinition();/把数据库中取出gpd.xml文件,转换成字节数组byte gpdBytes = pd.getFileDefinition().getBytes(“gpd.xml“);/获得根元素Element rootElement = DocumentHelper.parseText(new String(gpdBytes,“utf-8“).getRootElement();/获得流程宽和高int processWitdth = Integer.parseInt(rootElement.at
24、tributeValue(“width“);int processHeight = Integer.parseInt(rootElement.attributeValue(“height“); String xpathStr = “/nodename=“+nodeName+“; /通过xpath查询当前节点XPath xPath = new DefaultXPath(xpathStr);Element nodeXML = (Element)xPath.selectSingleNode(rootElement);,编码转换,否则中文无法解析,jBPM + SSH整合步骤,String image
25、Url = request.getContextPath()+“/processImageServlet?pdId=“+pd.getId(); /流程URLint nodeWidth = Integer.parseInt(nodeXML.attributeValue(“width“); /获得节点的宽int nodeheight = Integer.parseInt(nodeXML.attributeValue(“height“); /获得节点的高 int nodeX = Integer.parseInt(nodeXML.attributeValue(“x“); /获得节点坐标x轴位置int
26、nodeY = Integer.parseInt(nodeXML.attributeValue(“y“); /获得节点坐标y轴位置out.println(pd.getName()+“流程的流程图如下:“);/流程图作为背景out.println(“);/输出当前节点位置out.println(“);out.println(“);out.println(“);out.flush();out.close(); catch (Exception e) e.printStackTrace();finallyjbpmContext.close();return null; ,jBPM + SSH整合步骤,查看请假单在部门主管处的流程图,总结,掌握使SSH能够支持jBPM的方法 jBPM整合SSH的步骤 jBPM的Web工程中邮件的使用 jBPM流程图的显示 jBPM中流程节点的高亮显示,