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

本文介绍了如何使用JBPM4.4实现一个简单的请假流程,包括配置文件设置、流程定义、Web应用配置以及关键Java代码。流程涉及请假申请、经理审批和老板审批三个环节,通过servlet进行交互。详细步骤和代码示例帮助读者理解工作流的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近学习了一下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

至此,一个完整的流程就执行完毕了。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sust2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值