您的位置:首页 > 产品设计 > 产品经理

JBPM4.4 入门 简单的请假流程

2013-11-28 11:01 344 查看
最近学习了一下jbpm工作流,感觉网上好多例子都不是很全,所以就做了一个完整的流程,使用jsp和servlet

1 . jbpm的配置文件

(1) jbpm.cg.xml ,该文件可以从下载的jbpm4.4.rar 的example例子里面拷贝到。

<?xml version="1.0" encoding="UTF-8"?>

<jbpm-configuration>

<import resource="jbpm.default.cfg.xml" />

<import resource="jbpm.businesscalendar.cfg.xml" />

<import resource="jbpm.tx.hibernate.cfg.xml" />

<import resource="jbpm.jpdl.cfg.xml" />

<import resource="jbpm.bpmn.cfg.xml" />

<import resource="jbpm.identity.cfg.xml" />

</jbpm-configuration>

2. jbpm.hibernate.cfg.xml 主要是hibernate的配置,也可以从example例子里面拷贝到

<?xml version='1.0' encoding='UTF-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

<property name="connection.url">jdbc:oracle:thin:@10.163.100.54:1521:test</property>

<property name="connection.username">scott</property>

<property name="connection.password">tiger</property>

<property name="format_sql">true</property>

<property name="dialect">org.hibernate.dialect.OracleDialect</property>

<!-- <property name="hbm2ddl.auto">update</property>

该属性用户自动的生成jbpm的表-->

<property name="dialect">org.hibernate.dialect.OracleDialect</property>

<mapping resource="jbpm.repository.hbm.xml" />

<mapping resource="jbpm.execution.hbm.xml" />

<mapping resource="jbpm.history.hbm.xml" />

<mapping resource="jbpm.task.hbm.xml" />

<mapping resource="jbpm.identity.hbm.xml" />

</session-factory>

</hibernate-configuration>

3. jbpm的流程定义文件,这个需要在eclipse中装完插件,就可以画流程,文件如下leaveApply.jpdl.xml

<?xml version="1.0" encoding="UTF-8"?>

<process key="leave" name="leave" xmlns="http://jbpm.org/4.4/jpdl">

<start g="-2,137,48,48" name="start1">

<transition g="-21,-30" name="apply" to="leave_app_fill"/>

</start>

<end g="475,136,48,48" name="end1"/>

<task assignee="leaveUser" g="86,135,92,52" name="leave_app_fill">

<transition g="-26,-32" name="isManager" to="isManager"/>

</task>

<task assignee="bossUser" g="327,65,107,52" name="boss_operate">

<transition g="1,-18" name="b_notApprove" to="end1"/>

<transition g="637,89:-129,-25" name="boss_approve" to="end2"/>

<transition g="132,93:49,-21" name="reject" to="leave_app_fill"/>

</task>

<decision expr="#{isManager}" g="223,138,48,48" name="isManager">

<transition g="-20,-23" name="yes" to="boss_operate"/>

<transition g="-38,7" name="no" to="manager_operate"/>

</decision>

<end g="614,138,48,48" name="end2"/>

<task assignee="manageUser" g="329,192,115,52" name="manager_operate">

<transition g="3,3" name="m_notApprove" to="end1"/>

<transition g="532,219;642,217:-42,8" name="man_approve" to="end2"/>

<transition g="-49,-22" name="day>3" to="boss_operate"/>

<transition g="134,218:61,3" name="reject" to="leave_app_fill"/>

</task>

</process>

流程图如下:



4. web.xml 的配置

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>

<context-param>

<param-name>workflowFileName</param-name>

<param-value>leaveApply.jpdl.xml</param-value>

</context-param>

<servlet>

<servlet-name>LeaveServlet</servlet-name>

<servlet-class>com.jbpm.workflow.servlet.LeaveServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>LeaveServlet</servlet-name>

<url-pattern>/LeaveServlet</url-pattern>

</servlet-mapping>

</web-app>

2. java文件

1. servlet

package com.jbpm.workflow.servlet;

import java.io.IOException;

import java.util.List;

import java.util.Map;

import javax.servlet.ServletConfig;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.jbpm.api.task.Task;

import com.jbpm.workflow.util.JBPMUtil;

public class LeaveServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

public void init(ServletConfig config) throws ServletException {

//服务器启动时加载流程并发布

String flowFileName = config.getServletContext().getInitParameter("workflowFileName");

System.out.println("flowFileName:--------------:"+flowFileName);

JBPMUtil.depoloy(flowFileName);

}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

response.setContentType("text/html;charset=utf-8");

response.setCharacterEncoding("utf-8");

request.setCharacterEncoding("utf-8");

String operate = request.getParameter("operate");

System.out.println("operate:-------------:"+operate);

JBPMUtil jbmpUtil = new JBPMUtil();

//拿试图的key启动该流程,启动成功后跳到请假页面

if(null != operate && "applyLeave".equals(operate)){

String url = jbmpUtil.applyLeave();

request.getRequestDispatcher(url).forward(request, response);

return ;

}

//请假页面的提交,提交到判断的节点

if(null != operate && "apply".equals(operate)){

jbmpUtil.apply(request, response);

request.setAttribute("pi", JBPMUtil.processInstance);

request.getRequestDispatcher("/index.jsp").forward(request, response);

return ;

}

//根据审批人的名称查询,该审批人的task

if(null != operate && "getTask".equals(operate)){

List<Task> taskList = jbmpUtil.getTask(request, response);

request.setAttribute("taskList", taskList);

request.getRequestDispatcher("/check.jsp").forward(request, response);

return ;

}

/*

* 审批人进行审批

* 1. 批准

* 2. 不批准

*/

//1.批准

if(null != operate && "approve".equals(operate)){

//批准电子流

jbmpUtil.approve(request, response);

//批准后重新查询审批人当前的task

List<Task> taskList = jbmpUtil.getTask(request, response);

request.setAttribute("taskList", taskList);

request.getRequestDispatcher("/check.jsp").forward(request, response);

return ;

}

//2.不批准

if(null != operate && "notApprove".equals(operate)){

//走不批准流程

jbmpUtil.disApprove(request, response);

//不批准后重新查询审批人当前的task

List<Task> taskList = jbmpUtil.getTask(request, response);

request.setAttribute("taskList", taskList);

request.getRequestDispatcher("/check.jsp").forward(request, response);

return ;

}

//审批前可以查看查看当前任务中的参数

//2.不批准

if(null != operate && "view".equals(operate)){

//走不批准流程

Map<String,Object> varibleMap = jbmpUtil.view(request);

//不批准后重新查询审批人当前的task

request.setAttribute("varibleMap", varibleMap);

request.getRequestDispatcher("/view.jsp").forward(request, response);

return ;

}

}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

this.doGet(request, response);

}

}

2. 工具类

package com.jbpm.workflow.util;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.jbpm.api.Configuration;

import org.jbpm.api.Execution;

import org.jbpm.api.ExecutionService;

import org.jbpm.api.ProcessEngine;

import org.jbpm.api.ProcessInstance;

import org.jbpm.api.RepositoryService;

import org.jbpm.api.TaskService;

import org.jbpm.api.task.Task;

public class JBPMUtil {

public static RepositoryService repositoryService;

public static ExecutionService executionService ;

public static TaskService taskService ;

public static ProcessInstance processInstance ;

/*

* 发布一个流程,输入流程的文件名称,发布成功后给流程的service赋值

*/

public static void depoloy(String flowFileName){

System.out.println("开始发布流程...........");

ProcessEngine processEngine = new Configuration().buildProcessEngine();

repositoryService = processEngine.getRepositoryService();

repositoryService.createDeployment().addResourceFromClasspath(flowFileName).deploy();

executionService = processEngine.getExecutionService();

taskService = processEngine.getTaskService();

System.out.println("流程发布完毕...........");

}

/*

* 根据流程的名字启动一个新的流程实例

*

*/

public String applyLeave(){

System.out.println("启动请假流程.....");

String url = "";

processInstance = executionService.startProcessInstanceByKey("leave");

//判断流程是否启动成功,启动成功的话,跳转到填写申请的页面

if(processInstance.isActive("leave_app_fill")){

url = "applyLeave.jsp";

}

return url ;

}

/*

* 请假提交后,判断节点的处理

*/

public Map<String,Object> apply(HttpServletRequest request,HttpServletResponse response){

Map<String,Object> paramMap = new HashMap<String,Object> ();

String applyName = request.getParameter("applyName");

String position = request.getParameter("position");

String applyTime = request.getParameter("applyTime");

String leaveDay = request.getParameter("leaveDay");

String content = request.getParameter("content");

System.out.println("applyName:"+applyName);

paramMap.put("applyName", applyName);

paramMap.put("position", position);

paramMap.put("applyTime", applyTime);

paramMap.put("leaveDay", leaveDay);

paramMap.put("content", content);

System.out.println("position:"+position);

String isManager = "no"; //isManager 必须与流程中定义的名字一致

if(position.trim().toUpperCase().equals("经理")){

isManager = "yes";

}

paramMap.put("isManager", isManager);

System.out.println("流程流向: ismanager:"+isManager);

//leave.jbdl.xml中 该任务被分配给 leaveUser,根据分配者,查找该人的所有任务列表

List<Task> taskList = taskService.findPersonalTasks("leaveUser");

Task task = taskList.get(0);

//把设置好的变量放到流程服务里面去

taskService.setVariables(task.getId(), paramMap);

taskService.completeTask(task.getId());

//根据流程定义id获取流程实例

System.out.println("processInstance.id:"+processInstance.getId()+"-----processInstance:"+processInstance.getState());

processInstance = executionService.findProcessInstanceById(processInstance.getId());

System.out.println("processInstance.id:"+processInstance.getId()+"-----processInstance:"+processInstance.getState());

System.out.println("executionService.id:"+executionService);

return paramMap;

}

/*

* 根据当前处理人,查询出给人的所有任务

*/

public List<Task> getTask(HttpServletRequest request ,HttpServletResponse response){

List<Task> list = null ;

String name = request.getParameter("name");

System.out.println("查询:"+name+":的task");

list = taskService.findPersonalTasks(name);

return list ;

}

/*

* 批准

*/

public void approve(HttpServletRequest request ,HttpServletResponse response){

String taskId = request.getParameter("taskid");

Task task = taskService.getTask(taskId);

Execution execution = executionService.findExecutionById(task.getExecutionId());

System.out.println("taskId:"+taskId+"---executionId:"+task.getExecutionId());

//如果是boss的话,同意的话,流程直接走approve

if(execution.isActive("boss_operate")){

taskService.completeTask(taskId, "boss_approve");

}

//如果为manager的话,判断是否大于3天,如果大于的话就提交boss,负责manager直接走approve

else if(execution.isActive("manager_operate")){

// 从流程的参数表中取请假的天数

String leaveDay = (String) taskService.getVariable(taskId, "leaveDay");

System.out.println("leaveDay from flow variable:"+leaveDay);

//天数大于3的话提交boss审批

if(Integer.parseInt(leaveDay)>3){

taskService.completeTask(taskId, "day>3");

}else{

taskService.completeTask(taskId, "man_approve");

}

}

}

/*

* 不批准

*/

public void disApprove(HttpServletRequest request ,HttpServletResponse response){

String taskId = request.getParameter("taskid");

Task task = taskService.getTask(taskId);

Execution execution = executionService.findExecutionById(task.getExecutionId());

if(execution.isActive("manager_operate")){

taskService.completeTask(taskId, "m_notApprove");

}

else if(execution.isActive("boss_operate")){

taskService.completeTask(taskId, "b_notApprove");

}

}

/*

* 查看节点的参数

*/

public Map<String ,Object> view(HttpServletRequest request){

Map <String,Object> varibleMap = null ;

String taskId = request.getParameter("taskid");

Set<String> taskNameSet = taskService.getVariableNames(taskId);

for (String string : taskNameSet) {

System.out.println("varibleName:"+string);

}

varibleMap = taskService.getVariables(taskId, taskNameSet);

for (Map.Entry<String, Object> entry :varibleMap.entrySet()) {

System.out.println(entry.getKey()+":"+entry.getValue());

}

return varibleMap ;

}

}

3. 前台jsp

1. 初始界面 index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" isELIgnored="false"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

<ul>

<li><a href="LeaveServlet?operate=applyLeave">请假</a></li>

<li><a href="LeaveServlet?operate=getTask&name=manageUser" target="_blank">经理的待办</a></li>

<li><a href="LeaveServlet?operate=getTask&name=bossUser" target="_blank">老板的待办</a></li>

</ul>

<table>

<tr>

<td>${pi.id}|</td>

<td>${pi.key}|</td>

<td>${pi.name}|</td>

<td>${pi.state}|</td>

</tr>

</table>

</body>

</html>

2. 请假界面 applyLeave.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" isELIgnored="false" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

<form action="LeaveServlet?operate=apply" method="post">

<table width="300" border=1>

<tr>

<td><label>申请人</label></td>

<td><input type="text" value="leaveUser" name="applyName"></td>

</tr>

<tr>

<td><label>职位</label></td>

<td><input type="text" value="经理" name="position"></td>

</tr>

<tr>

<td><label>申请时间</label></td>

<td><input type="text" value="2009-03-09" name="applyTime"></td>

</tr>

<tr>

<td><label>请假天数</label></td>

<td><input type="text" value="3" name="leaveDay"></td>

</tr>

<tr>

<td><label>请假原因</label></td>

<td><textarea name="content" rows=3 cols=200>病假</textarea></td>

</tr>

<tr>

<td><input type="submit" value="申请"></td>

<td><input type="reset" value="取消"></td>

</tr>

</table>

</form>

</body>

</html>

3. 审批(同意/不同意)界面 check.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" isELIgnored="false" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="f" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>task list</title>

</head>

<body>

<table>

<tr>

<th>ID</th>

<th>流程名称</th>

<th>分配人</th>

<th>创建时间</th>

<th>持续时间</th>

<th>优先级</th>

<th>描述</th>

<th>操作</th>

</tr>

<c:forEach items="${requestScope.taskList}" var="task">

<tr>

<td>${task.id}</td>

<td>${task.name}</td>

<td>${task.assignee}</td>

<td><f:formatDate pattern="yyyy-MM-dd" value="${task.createTime}"/></td>

<td><f:formatDate pattern="yyyy-MM-dd" value="${task.duedate}"/></td>

<td>${task.priority}</td>

<td>${task.description}</td>

<td>

<a href="LeaveServlet?operate=view&taskid=${task.id}" target="_blank">审核</a>

<a href="LeaveServlet?operate=approve&taskid=${task.id}&name=${task.assignee}">批准</a>

<a href="LeaveServlet?operate=notApprove&taskid=${task.id}&name=${task.assignee}">不批准</a>

</td>

</tr>

</c:forEach>

</table>

</body>

</html>

4. 审核页面(查看具体的请假参数)view.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" isELIgnored="false" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

<table>

<c:forEach items="${varibleMap}" var="vMap">

<tr>

<td>${vMap.key}</td>

<td>${vMap.value}</td>

</tr>

</c:forEach>

</table>

</body>

</html>

以上流程中的用户都是 限定死的

请假者 leaveUser

manager:manageUser

boss: bossUser

至此,一个完整的流程就执行完毕了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: