JBPM4基础篇-设计请假流程,流程的发起,执行,驳回,监控web Demo

  • 本次,我们在web项目的基础上,设计一个请假流程。申请--->经理审批---->老板审批----->通过。中间有根据一些条件来做判断,让流程进入到不同的节点。
  • 还有,加入了流程监控的功能。


  1. leave.jpdl.xml

    [html]  view plain copy
    1. xml version="1.0" encoding="UTF-8"?>  
    2.   
    3. <process name="leave" xmlns="http://jbpm.org/4.3/jpdl">  
    4.    <start g="199,100,48,48" name="start1">  
    5.       <transition to="申请"/>  
    6.    start>  
    7.    <task assignee="#{owner}" form="request.jsp" g="178,190,92,52" name="申请">  
    8.       <transition to="经理审批"/>  
    9.    task>  
    10.    <task assignee="manager" form="manager.jsp" g="182,322,92,52" name="经理审批">  
    11.       <transition g="-37,-11" name="批准" to="exclusive1"/>  
    12.       <transition name="驳回" to="申请" g="108,350;106,216:-30,-7"/>  
    13.    task>  
    14.    <task assignee="boss" form="boss.jsp" g="358,471,92,52" name="老板审批">  
    15.       <transition g="406,571:-47,-17" name="to end1" to="end1"/>  
    16.    task>  
    17.    <decision expr="#{day > 3 ? 'to 老板审批' : 'to end1'}" g="208,425,48,48" name="exclusive1">  
    18.       <transition g="-47,-17" name="to end1" to="end1"/>  
    19.       <transition g="405,448:-71,-17" name="to 老板审批" to="老板审批"/>  
    20.    decision>  
    21.    <end g="211,549,48,48" name="end1"/>  
    22. process>  

  2. login.jsp
    由于在测试的过程中,要展示某某用户有哪些待办流程,或者某某用户发起了一个新流程,所以,做了一个简易的登录页面,登录后,保存当前登录的userName。
    [html]  view plain copy
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2.     pageEncoding="UTF-8"%>  
    3. >  
    4. <html>  
    5. <head>  
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    7. <title>登录title>  
    8. head>  
    9. <body>  
    10.   
    11. body>  
    12.     <form name="loginForm" action="doLogin.jsp" method="post">  
    13.         <div>  
    14.             请输入用户名:<input type="text" name="userName" />   
    15.             <input type="submit" value="登录" />  
    16.         div>  
    17.     form>  
    18. html>  

    效果图如下:

  3. index.jsp
    在index页面,有显示流程列表,显示已经启动的流程列表,有待办任务列表
    [html]  view plain copy
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2.     pageEncoding="UTF-8"%>  
    3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>  
    4. <%@ include file="checkLogin.jsp" %>  
    5. <%  
    6.     String userName = (String)session.getAttribute("userName");  
    7.     ProcessEngine processEngine = Configuration.getProcessEngine(); // 创建一个流程引擎  
    8.     RepositoryService repositoryService = processEngine.getRepositoryService(); // 创建一个流程服务  
    9.     ExecutionService executionService = processEngine.getExecutionService(); // 实例服务  
    10.     TaskService taskService = processEngine.getTaskService(); // 任务  
    11.       
    12.     List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list(); // 获取流程列表  
    13.     List<ProcessInstance> piList = executionService.createProcessInstanceQuery().list(); // 获取实例列表  
    14.     List<Task> taskList = taskService.findPersonalTasks(userName);  
    15.       
    16. %>  
    17. >  
    18. <html>  
    19. <head>  
    20. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    21. <title>Insert title heretitle>  
    22. <link rel="Stylesheet" type="text/css" href="style.css" />  
    23. head>  
    24. <body>  
    25.     <div>  
    26.         当前登录用户[<%=userName %>]|  
    27.         <a href="deploy.jsp">发布新流程a>|<a href="login.jsp">登录a>  
    28.     div>  
    29.     <div>  
    30.         <h2>流程列表h2>  
    31.         <table>  
    32.             <tr>  
    33.                 <td>IDtd>  
    34.                 <td>Nametd>  
    35.                 <td>Versiontd>  
    36.                 <td>操作td>  
    37.             tr>  
    38.         <%    
    39.             for(ProcessDefinition pd : list) {  
    40.         %>  
    41.             <tr>  
    42.                 <td><%=pd.getId() %>td>  
    43.                 <td><%=pd.getName() %>td>  
    44.                 <td><%=pd.getVersion() %>td>  
    45.                 <td>  
    46.                     <a href="remove.jsp?deploymentId=<%=pd.getDeploymentId() %>">删除a>|  
    47.                     <a href="start.jsp?id=<%=pd.getId() %>">开始a>  
    48.                 td>  
    49.             tr>  
    50.         <%  
    51.             }  
    52.         %>  
    53.         table>  
    54.           
    55.         <h2>实例列表h2>  
    56.         <table>  
    57.             <tr>  
    58.                 <td>IDtd>  
    59.                 <td>活动td>  
    60.                 <td>状态td>  
    61.                 <td>操作td>  
    62.             tr>  
    63.         <%    
    64.             for(ProcessInstance pi : piList) {  
    65.         %>  
    66.             <tr>  
    67.                 <td><%=pi.getId() %>td>  
    68.                 <td><%=pi.findActiveActivityNames() %>td>  
    69.                 <td><%=pi.getState() %>td>  
    70.                 <td><a href="view.jsp?id=<%=pi.getId() %>">查看a>td>  
    71.             tr>  
    72.         <%  
    73.             }  
    74.         %>  
    75.         table>  
    76.           
    77.             <h2>任务列表h2>  
    78.         <table>  
    79.             <tr>  
    80.                 <td>IDtd>  
    81.                 <td>名称td>  
    82.                 <td>操作td>  
    83.             tr>  
    84.         <%    
    85.             for(Task task : taskList) {  
    86.         %>  
    87.             <tr>  
    88.                 <td><%=task.getId() %>td>  
    89.                 <td><%=task.getName() %>td>  
    90.                 <td><a href="<%=task.getFormResourceName() %>?taskId=<%=task.getId() %>">查看a><br />td>  
    91.             tr>  
    92.         <%  
    93.             }  
    94.         %>  
    95.         table>  
    96.     div>  
    97.   
    98. body>  
    99. html>  

    页面展示效果如下:

  4. deploy.jsp
    当在index页面点击“发布新流程”超链接的时候,发起一个新的流程。

    [java]  view plain copy
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2.     pageEncoding="UTF-8"%>  
    3. <%@ page import="java.util.*,org.jbpm.api.*"%>  
    4. <%  
    5.     ProcessEngine processEngine = Configuration.getProcessEngine(); // 创建一个流程引擎  
    6.     RepositoryService repositoryService = processEngine  
    7.             .getRepositoryService(); // 创建一个流程服务  
    8.   
    9.     repositoryService.createDeployment()  
    10.             .addResourceFromClasspath("leave.jpdl.xml").deploy(); // 发布一个流程  
    11.   
    12.     response.sendRedirect("index.jsp");  
    13. %>  


    发起一个流程后,index页面的效果如下:
  5. start.jsp
    点击首页流程列表中的“开始”,将当前的流程ID获取到,然后根据这个流程ID来启动一个流程
    [java]  view plain copy
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2.     pageEncoding="UTF-8"%>  
    3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>  
    4. <%  
    5.     String id = request.getParameter("id");  
    6.     String userName = (String)session.getAttribute("userName");  
    7.       
    8.     ProcessEngine processEngine = Configuration.getProcessEngine(); // 创建流程引擎  
    9.     ExecutionService executionService = processEngine.getExecutionService(); //   
    10.       
    11.     Map map = new HashMap();  
    12.     map.put("owner", userName);  
    13.     executionService.startProcessInstanceById(id, map);  
    14.       
    15.     response.sendRedirect("index.jsp");  
    16. %>  

    开始一个流程后,index页面的效果图如下:
  6. request.jsp
    假设当前登录用户为owner,由owner发起的流程,现在进入了申请阶段。任务列表中显示的是属于当前用户的待办列表。点击进去查看详情并提交申请。
    [html]  view plain copy
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2.     pageEncoding="UTF-8"%>  
    3. >  
    4. <html>  
    5. <head>  
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    7. <title>Requesttitle>  
    8. <link rel="Stylesheet" type="text/css" href="style.css" />  
    9. head>  
    10. <body>  
    11.     <h2>申请h2>  
    12.     <form action="submit.jsp" method="post">  
    13.         <input type="hidden" name="taskId" value="${param.taskId }" />  
    14.         <table>  
    15.             <tr>  
    16.                 <td>申请人td>  
    17.                 <td><input type="text" name="owner" value="${sessionScope['userName'] }"/>td>  
    18.             tr>  
    19.             <tr>  
    20.                 <td>请假时间(天)td>  
    21.                 <td><input type="text" name="day" value="" />td>  
    22.             tr>  
    23.             <tr>  
    24.                 <td>请假原因td>  
    25.                 <td><input type="text" name="reason" value="" />td>  
    26.             tr>  
    27.         table>  
    28.         <input type="submit" value="提交" />  
    29.     form>  
    30. body>  
    31. html>  

    效果图如下:
  7. submit.jsp
    当申请人提交了申请之后,我们需要获取其申请单提交的表单元素,将其执行使之进入下一步流程
    [java]  view plain copy
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2.     pageEncoding="UTF-8"%>  
    3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>  
    4. <%  
    5.     request.setCharacterEncoding("UTF-8");  
    6.     ProcessEngine processEngine = Configuration.getProcessEngine();  
    7.     TaskService taskService = processEngine.getTaskService();  
    8.   
    9.     // 接收任务ID  
    10.     String taskId = request.getParameter("taskId");  
    11.     // 接收用户名  
    12.     String owner = request.getParameter("owner");  
    13.     // 接收请假天数  
    14.     int day = Integer.parseInt(request.getParameter("day"));  
    15.     // 接收请假原因  
    16.     String reason = request.getParameter("reason");  
    17.       
    18.     Map map = new HashMap();  
    19.     map.put("day", day);  
    20.     map.put("reason", reason);  
    21.       
    22.     // 执行任务  
    23.     taskService.completeTask(taskId, map);  
    24.       
    25.     // 跳转到首页  
    26.     response.sendRedirect("index.jsp");  
    27. %>  

    提交了申请之后,再看index页面,刚才的待办任务已经流转,不显示了。如下图:


    然后使用manager(在leave.jpdl.xml中有定义)登录,查看属于自己的待办任务列表;如下图:


    登录首页后,清楚的看到刚才owner提交的申请已经流转到了manager的名下;如下图:
  8. manager.jsp
    点击index的待办任务列表中“查看”时,JBPM会根据在leave.jpdl.xml中的配置的form属性,自动跳转到manager页面进行经理的审批和驳回;
    [html]  view plain copy
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2.     pageEncoding="UTF-8"%>  
    3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>  
    4. <%  
    5.     ProcessEngine processEngine = Configuration.getProcessEngine();  
    6.     TaskService taskService = processEngine.getTaskService();  
    7.     String taskId = request.getParameter("taskId");  
    8.     Task task = taskService.getTask(taskId); // 获取任务  
    9. %>  
    10. >  
    11. <html>  
    12. <head>  
    13. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    14. <title>Managertitle>  
    15. <link rel="Stylesheet" type="text/css" href="style.css" />  
    16. head>  
    17. <body>  
    18.     <h2>经理审核h2>  
    19.     <form action="submit_manager.jsp" method="post">  
    20.         <input type="hidden" name="taskId" value="${param.taskId }" />  
    21.         <table>  
    22.             <tr>  
    23.                 <td>申请人td>  
    24.                 <td><%=taskService.getVariable(taskId, "owner") %>td>  
    25.             tr>  
    26.             <tr>  
    27.                 <td>请假时间(天)td>  
    28.                 <td><%=taskService.getVariable(taskId, "day") %>td>  
    29.             tr>  
    30.             <tr>  
    31.                 <td>请假原因td>  
    32.                 <td><%=taskService.getVariable(taskId, "reason") %>td>  
    33.             tr>  
    34.         table>  
    35.         <input type="submit" name="result" value="批准" />  
    36.         <input type="submit" name="result" value="驳回" />  
    37.     form>  
    38. body>  
    39. html>  

    效果图如下:
  9. submit_manager.jsp
    manager在提交了审批结果之后,在这里要处理经理提交的结果,批准或者驳回
    [java]  view plain copy
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2.     pageEncoding="UTF-8"%>  
    3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>  
    4. <%  
    5.     request.setCharacterEncoding("UTF-8");  
    6.     ProcessEngine processEngine = Configuration.getProcessEngine();  
    7.     TaskService taskService = processEngine.getTaskService();  
    8.   
    9.     // 接收任务ID  
    10.     String taskId = request.getParameter("taskId");  
    11.     // 接受命令  
    12.     String result = request.getParameter("result");  
    13.       
    14.     // 执行任务  
    15.     /* 
    16.      * jbpm会根据传过去的result来判断流程转向哪个task 
    17.      */  
    18.     taskService.completeTask(taskId, result);  
    19.       
    20.     // 跳转到首页  
    21.     response.sendRedirect("index.jsp");  
    22. %>  

    如果批准,我们再看index页面,属于经理的待办任务已经没了。并且,流程的实例列表也空了,证明这个流程已经流转完毕;如下图:


    我们再创建一个新的流程来测试驳回的效果;结果如下图:


  10. view.jsp和pic.jsp
    点击首页实例列表中的“查看”链接即可查看当前流程走到了哪一步,实现了流程监控


    然后view页面会将此时流程图显示出来,并且能看到当前走到了哪一步;要实现这个,必须进行以下三步:
    第一:将leave.jpdl.xml和自动生成的leave.png打包到一个leave.zip文件中(注意不要包含任何一层多的文件夹),并且存放在src下或者根目录下。如下图:



    第二:view.jsp
    [html]  view plain copy
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2.     pageEncoding="UTF-8"%>  
    3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.model.*"%>  
    4. <%  
    5.     String id = request.getParameter("id"); // 获取流程实例ID  
    6.     ProcessEngine processEngine = Configuration.getProcessEngine();  
    7.     RepositoryService repositoryService = processEngine  
    8.             .getRepositoryService();  
    9.     ExecutionService executionService = processEngine  
    10.             .getExecutionService();  
    11.     ProcessInstance processInstance = executionService  
    12.             .findProcessInstanceById(id); // 根据ID获取流程实例  
    13.     Set<String> activityNames = processInstance  
    14.             .findActiveActivityNames(); // 获取实例执行到的当前节点的名称  
    15.   
    16.     ActivityCoordinates ac = repositoryService.getActivityCoordinates(  
    17.             processInstance.getProcessDefinitionId(), activityNames  
    18.                     .iterator().next());  
    19. %>  
    20. >  
    21. <html>  
    22. <head>  
    23. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    24. <title>Viewtitle>  
    25. <link rel="Stylesheet" type="text/css" href="style.css" />  
    26. head>  
    27. <body>  
    28.     <h2>流程图显示h2>  
    29.     <img src="pic.jsp?id=<%=id%>"  
    30.         style="position: absolute; left: 0px; top: 0px" />  
    31.     <div  
    32.         style="position:absolute;border:2px solid red;left:<%=ac.getX()%>px;top:<%=ac.getY()%>px;width:<%=ac.getWidth()%>px;height:<%=ac.getHeight()%>px;">div>  
    33. body>  
    34. html>  

    第三:pic.jsp(在view.jsp中调用了pic.jsp来获取图片)
    [java]  view plain copy
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2.     pageEncoding="UTF-8"%>  
    3. <%@ page import="java.util.*,org.jbpm.api.*,java.io.*"%>  
    4. <%  
    5.     String id = request.getParameter("id"); // 获取流程实例ID  
    6.     ProcessEngine processEngine = Configuration.getProcessEngine();  
    7.     RepositoryService repositoryService = processEngine  
    8.             .getRepositoryService();  
    9.     ExecutionService executionService = processEngine  
    10.             .getExecutionService();  
    11.     ProcessInstance processInstance = executionService  
    12.             .findProcessInstanceById(id); // 根据ID获取流程实例  
    13.     String processDefinitionId = processInstance  
    14.             .getProcessDefinitionId();  
    15.     ProcessDefinition processDefinition = repositoryService  
    16.             .createProcessDefinitionQuery()  
    17.             .processDefinitionId(processDefinitionId).uniqueResult();  
    18.     InputStream inputStream = repositoryService.getResourceAsStream(  
    19.             processDefinition.getDeploymentId(), "leave.png");  
    20.       
    21.     byte[] b = new byte[1024];  
    22.     int len = -1;  
    23.     OutputStream ops = response.getOutputStream();  
    24.     while ((len = inputStream.read(b, 01024)) != -1) {  
    25.         ops.write(b, 0, len);  
    26.     }  
    27. %>  

    OK,现在我们来看看,当前的展示效果:

    上图的红框是程序自动生成的,并非作图的效果;

  11. boss.jsp,submit_boss.jsp
    这个页面来处理经理审批过后,大于3天的请假流程(规则在leave.jpdl.xml中定义)。
    需要查看详细代码和运行效果,请下载我的完整项目:
    链接稍后奉上!
    点击此处去下载完整Demo

你可能感兴趣的:(Java,jbpm)