zoukankan      html  css  js  c++  java
  • JBPM4.4业务流程管理框架详细解读

    1. 什么是JBPM4.4业务流程管理框架?

    JBPM,全称是Java Business Process Management(业务流程管理),它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。

    相关概念:a: 从一个节点到另一个节点==>流转。b:程序预先设定的行为==>活动。

    2. JBPM工作流的特点

    2.1 直观描述业务流程

    采用了自己定义的JPDL:业务流程被看成是UML状态图,详细定义状态图中每个部分,起始、结束每个状态以及状态之间的转换。通过流程图的方式来呈现、直观描述业务流程。如图所示:

     

    2.2 使用Hibernate管理数据库

    通过Hibernate管理数据库,JBPM就可以把数据的管理分离出去,自己专注于业务流程。
     

    3 ProcessEngine的核心服务

    RespositoryService:流程定义的服务接口:包括流程定义的部署、查询、删除等操作。
     
    ExecutionService: 流程执行的服务接口:包括启动流程、实例推进、设置变量等操作。
     
    ManagementService:Web管理控制台的服务接口,包括获得消息和计时器的操作。
     
    HistoryService:历史库的服务接口:包括对流程实例、活动实例进行查询。某个流程定义中的所有的活动的平均持续        时间,某个流程定义中的某个活动实例的转移的执行次数等操作。
     
    IdentityService:主要包括用户、组、成员关系等相关的操作
     
    CommondService:command模式的服务接口,实际上将客户端请求全部封装在一个调用接口中,execute(Command      cmd),由这个接口去调用command接口的众多实现类。
     

    4 怎么用JBMP?

    4.1 所需环境与相关资源

    1. jBPM requires a JDK (standard java) version 5 orhigher.
    3. Eclipse下载地址( Eclipse IDE for Java EE Developers (163 MB),Version:                  3.5):http://www.eclipse.org/downloads/download.php?    file=/technology/epp/downloads/release/galileo
     
     

    4.2 安装说明

    第一步:  

    Help -->Install New Software...

      ClickAdd...

      In dialogAdd Site dialog, clickArchive...

      Navigate toinstall/src/gpd/jbpm-gpd-site.zip and click 'Open'

      ClickingOK in theAdd Site dialog will bring you back to the dialog 'Install'

      Select thejPDL 4 GPD Update Site that has appeared

      ClickNext... and thenFinish

      Approve the license

      Restart eclipse when that is asked

     

    第二步:

    流程定义文件的xsd文件的路径为:JBPM_HOME/src/jpdl-4.4.xsd。

    添加到Eclipse中的方法为(jBPM4.4User Guide, 2.11.5. Adding jPDL 4 schema tothe catalog):

      ClickWindow -->Preferences

      SelectXML -->XML Catalog

      Click 'Add...'

      The 'Add XML Catalog Entry' dialog opens

      Click the button with the map-icon next to location and select 'FileSystem...'

      In the dialog that opens, select filejpdl-4.4.xsd in the src directoryof the jBPM installation root.

      Click 'Open' and close all the dialogs


     

    第三步:添加jar包

    1. JBPM解压目录下有一个重要的jar包:jbpm.jar。

    2. JBPM/lib目录下的jar很多,不要添加的jar包:servlet-api.jar、junit.jar(尤其不要添加)。

    3. 所使用的数据库对应的驱动的jar包在上面lib目录当中已经有了,所以不需要添加了。

    第四步: 添加配置文件

    1. 配置文件包括jbpm.cfg.xml和jbpm.hibernate.cfg.xml(解压包当中都有模板,直接拷贝即可)
    2. jbpm.hibernate.cfg.xml中配置的是Hibernate的配置信息,包括数据库连接的必要信息等等
    [html] view plain copy
     
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2.   
    3. <jbpm-configuration>  
    4.   
    5.   <import resource="jbpm.default.cfg.xml" />  
    6.   <import resource="jbpm.businesscalendar.cfg.xml" />  
    7.   <import resource="jbpm.tx.hibernate.cfg.xml" />  
    8.   <import resource="jbpm.jpdl.cfg.xml" />  
    9.   <import resource="jbpm.bpmn.cfg.xml" />  
    10.   <import resource="jbpm.identity.cfg.xml" />  
    11.   
    12.   <!-- Job executor is excluded for running the example test cases. -->  
    13.   <!-- To enable timers and messages in production use, this should be included. -->  
    14.   <!-- 
    15.   <import resource="jbpm.jobexecutor.cfg.xml" /> 
    16.   -->  
    17.   
    18. </jbpm-configuration>  
    jbpm.cfg.xml
     
    [html] view plain copy
     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2.   
    3. <!DOCTYPE hibernate-configuration PUBLIC  
    4.           "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
    5.           "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
    6.   
    7. <hibernate-configuration>  
    8.     <session-factory>  
    9.         <!-- 数据库信息 -->  
    10.         <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>  
    11.         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>  
    12.         <property name="hibernate.connection.url">jdbc:mysql:///jbpm4test</property>  
    13.         <property name="hibernate.connection.username">root</property>  
    14.         <property name="hibernate.connection.password">root</property>  
    15.   
    16.         <!-- 其他配置 -->  
    17.         <property name="hibernate.hbm2ddl.auto">update</property>  
    18.   
    19.         <!-- 导入映射文件 -->  
    20.         <mapping resource="jbpm.repository.hbm.xml" />  
    21.         <mapping resource="jbpm.execution.hbm.xml" />  
    22.         <mapping resource="jbpm.history.hbm.xml" />  
    23.         <mapping resource="jbpm.task.hbm.xml" />  
    24.         <mapping resource="jbpm.identity.hbm.xml" />  
    25.   
    26.     </session-factory>  
    27. </hibernate-configuration>  
    jbpm.hibernate.cfg.xml
     
    配置到此结束
     

    4.3 JBPM工作流的使用


    1. 创建jbpm的文件


     

    2. 绘制工作流程图

     

     
    绘制完成流程图之后,会相应的生成其xml中的代码(下面的代码便是自动生成的)
    [html] view plain copy
     
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2.   
    3. <process name="员工请假流程" xmlns="http://jbpm.org/4.4/jpdl">  
    4.    <start g="77,20,48,48" name="start1">  
    5.       <transition g="-71,-17" name="to 提交申请" to="提交申请"/>  
    6.    </start>  
    7.    <end g="77,352,48,48" name="end1"/>  
    8.    <task assignee="ww" g="55,268,92,52" name="总经理审批">  
    9.       <transition g="-47,-17" name="to end1" to="end1"/>  
    10.    </task>  
    11.    <task assignee="ls" g="55,184,92,52" name="部门经理审批">  
    12.       <transition g="-26,-8" name="同意" to="总经理审批"/>  
    13.    </task>  
    14.    <task assignee="#{applyInfo.applier.userName}" g="55,100,92,52" name="提交申请">  
    15.       <transition g="-96,-16" name="to 部门经理审批" to="部门经理审批"/>  
    16.    </task>  
    17. </process>  
    保存之后相应的生成png格式的对应的图片。
     

    4.4 JBPM工作流编程实例


    4.4.1 JBPM建表

     
    Hibernate会自动的帮我们把所需要的表建好。
    [java] view plain copy
     
    1.        // 建表  
    2. @Test  
    3. public void createSchema() {  
    4.     new org.hibernate.cfg.Configuration()//  
    5.         .configure("jbpm.hibernate.cfg.xml")//  
    6.         .buildSessionFactory();  
    7. }  
     

    4.4.2 创建ProcessEngine对象

     
    processEngine对象十分的重要,他是使用JBPM各类接口的切入点。
    1. 指定配置文件生成processEngine对象
    [java] view plain copy
     
    1. private static ProcessEngine processEngine = new Configuration()//  
    2.             .setResource("jbpm.cfg.xml")//  
    3.             .buildProcessEngine();  
     
    2. 使用默认的配置文件生成processEngine对象
    [java] view plain copy
     
    1. private ProcessEngine processEngine = new Configuration().buildProcessEngine();  

    3. 通过默认的配置文件生成单例的processEngine对象
    [java] view plain copy
     
    1. private ProcessEngine processEngine = Configuration.getProcessEngine();  

    4.4.3 部署流程定义

     
    流程定义:是这一次流程的步骤的说明,是对工作流程的静态式的说明信息。
    [java] view plain copy
     
    1. <span style="white-space:pre">    </span>// 部署流程定义  
    2.     @Test  
    3.     public void deployProcessDefinition()  
    4.     {  
    5.         String reponseStr = processEngine.getRepositoryService()//  
    6.             .createDeployment()//  
    7.             .addResourceFromClasspath("test/test.jpdl.xml")//这里目录需要根据自己的目录确定  
    8.             .addResourceFromClasspath("test/test.png")//  
    9.             .deploy();  
    10.         System.out.println(reponseStr);// 10001  
    11.     }  

    4.4.4 启动流程实例

     
    流程实例:代表工作流的一次执行,是一种动态的过程。
     
    1. 需要获得流程实例对象的时候
    [java] view plain copy
     
    1.        // 启动流程实例  
    2. // jbpm4_execution  
    3. @Test  
    4. public void testStartProcessInstance() throws Exception 
    5. {  
    6.     ProcessInstance processInstance = processEngine.getExecutionService().startProcessInstanceByKey("test");System.out.println("流程实例启动成功:id=" + processInstance .getId() + ", state=" +processInstance.getState() + ", processDefinitionId=" +  
      1. processInstance  
      .getProcessDefinitionId()); // 所使用的流程定义的ID
    7. }
    
    2. 通过key获取并直接启动实例
    [java] view plain copy
     
    1.        // 启动实例  
    2. @Test  
    3. public void startProcessInstance() {  
    4.     processEngine.getExecutionService().startProcessInstanceByKey("test");  
    5. }  

    4.4.5 查看个人的任务列表

     
    通过findPersonalTasks("person")可以获得具体的个人的任务列表
    [java] view plain copy
     
    1.        // 查询任务列表  
    2. @Test  
    3. public void findTaskList() {  
    4.     List<Task> taskList = processEngine.getTaskService().findPersonalTasks("员工");  
    5.     System.out.println("个人任务列表");  
    6.     System.out.println(taskList);  
    7.     for(Task task : taskList)  
    8.     {  
    9.         System.out.println("id= " + task.getId() + ", name = " + task.getName() + ", assignee = " + task.getAssignee());  
    10.     }  
    11. }  

    4.4.6 查询所有的流程定义

     
    [java] view plain copy
     
    1.        // 查询所有  
    2. @Test  
    3. public void findAll() throws Exception {  
    4.     // 查询  
    5.     List<ProcessDefinition> list = processEngine.getRepositoryService()//  
    6.             .createProcessDefinitionQuery()//  
    7.             // 过滤条件  
    8.             // .processDefinitionKey("")//  
    9.             // .processDefinitionNameLike("%xx%")//  
    10.             // 排序条件  
    11.             // .orderAsc(ProcessDefinitionQuery.PROPERTY_KEY)//  
    12.             // .orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION)//  
    13.             // 执行查询  
    14.             // .uniqueResult();  
    15.             // .count();  
    16.             // .page(firstResult, maxResults)//  
    17.             .list();  
    18.   
    19.     // 显示  
    20.     for (ProcessDefinition pd : list) {  
    21.     System.out.println("id=" + pd.getId()// 格式为:{key}-{version},用于唯一的标识一个流程定义  
    22.     + ", name=" + pd.getName()// 流程定义的名称,jpdl.xml中根元素的name属性的值  
    23.     + ", key=" + pd.getKey()// 流程定义的key,jpdl.xml中根元素的key属性的值,默认是name属性的值  
    24.     + ", version=" + pd.getVersion()// 自动生成的,同一个名称的第一个为1,以后的自动加1.  
    25.     + ", deploymentId=" + pd.getDeploymentId()); // 所属的部署对象  
    26.     }  
    27. }  

    4.4.7 查询最新版的流程定义

     
    [java] view plain copy
     
    1.        // 查询所有最新版本的流程定义  
    2. @Test  
    3. public void findAllLatestVersions() throws Exception {  
    4.     // 查询所有,让所有最大的版本都排到最后面  
    5.     List<ProcessDefinition> all = processEngine.getRepositoryService()//  
    6.             .createProcessDefinitionQuery()//  
    7.             .orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)//  
    8.             .list();  
    9.   
    10.     // 过滤出所有最新的版本  
    11.     Map<String, ProcessDefinition> map = new HashMap<String, ProcessDefinition>();  
    12.     for (ProcessDefinition pd : all) {  
    13.         map.put(pd.getKey(), pd);  
    14.     }  
    15.   
    16.     // 显示  
    17.     for (ProcessDefinition pd : map.values()) {  
    18.     System.out.println("id=" + pd.getId()// 格式为:{key}-{version},用于唯一的标识一个流程定义  
    19.     + ", name=" + pd.getName()// 流程定义的名称,jpdl.xml中根元素的name属性的值  
    20.     + ", key=" + pd.getKey()// 流程定义的key,jpdl.xml中根元素的key属性的值,默认是name属性的值  
    21.     + ", version=" + pd.getVersion()// 自动生成的,同一个名称的第一个为1,以后的自动加1.  
    22.     + ", deploymentId=" + pd.getDeploymentId()); // 所属的部署对象  
    23.     }  
    24. }  
     

    4.4.8 删除流程定义

     
    [java] view plain copy
     
    1.        // 删除  
    2. @Test  
    3. public void deleteById() throws Exception {  
    4.     String deploymentId = "80001";  
    5.   
    6.     // // 删除指定的部署对象(流程定义),如果有关联的执行信息,就会报错  
    7.     // processEngine.getRepositoryService().deleteDeployment(deploymentId);  
    8.   
    9.     // 删除指定的部署对象(流程定义),如果有关联的执行信息,会被同时删除  
    10.     processEngine.getRepositoryService().deleteDeploymentCascade(deploymentId);  
    11. }  
    [java] view plain copy
     
    1.        // 删除指定key的所有版本的流程定义  
    2. @Test  
    3. public void deleteByKey() throws Exception {  
    4.     // 查询出指定key的所有版本的流程定义  
    5.     List<ProcessDefinition> list = processEngine.getRepositoryService()//  
    6.             .createProcessDefinitionQuery()//  
    7.             .processDefinitionKey("helloworld")//  
    8.             .list();  
    9.   
    10.     // 一一删除  
    11.     for (ProcessDefinition pd : list) {  
    12.         processEngine.getRepositoryService().deleteDeploymentCascade(pd.getDeploymentId());  
    13.     }  
    14. }  

    4.4.9 查看流程图

     
    [java] view plain copy
     
    1.        // 查看流程图(xxx.png)  
    2. @Test  
    3. public void getImageResource() throws Exception {  
    4.     String deploymentId = "50001";  
    5.     String resourceName = "helloworld/helloworld.png";  
    6.   
    7.     // 获取指定部署对象中的所有资源的名称  
    8.     Set<String> names = processEngine.getRepositoryService().getResourceNames(deploymentId);  
    9.     System.out.println("所有的资源名称:");  
    10.     for (String name : names) {  
    11.         System.out.println(" " + name);  
    12.     }  
    13.   
    14.     // 获取指定部署对象中的指下资源的内容  
    15. InputStream in = processEngine.getRepositoryService().getResourceAsStream(deploymentId, resourceName);  
    16.   
    17.     // 保存到c盘  
    18.     OutputStream out = new FileOutputStream("c:/process.png");  
    19.     for (int b = -1; (b = in.read()) != -1;) {  
    20.         out.write(b);  
    21.     }  
    22.     in.close();  
    23.     out.close();  
    24. }  
     

    4.4.10 向后执行一步

    [java] view plain copy
     
    1.        // 向后执行一步  
    2. @Test  
    3. public void testSignalExecution() throws Exception {  
    4.     String executionId = "test.130001";  
    5.     processEngine.getExecutionService().signalExecutionById(executionId);  
    6.   
    7.                         // processEngine.getExecutionService().signalExecutionById(executionId, parametersMap);                         // 离开前先设置一些流程变量  
    8.              // processEngine.getExecutionService().signalExecutionById(executionId, signalName);                            // 使用指定名称的Transition离开本活动  
    9.      // processEngine.getExecutionService().signalExecutionById(executionId, signalName, parameters)                         // 离开前先设置一些流程变量,再使用指定名称的Transition离开本活动  
    10.   
    11. }  

    4.4.11 办理任务

     
    [java] view plain copy
     
    1.        // 办理任务  
    2. @Test  
    3. public void testCompleteTask() throws Exception {  
    4.     String taskId = "130002";  
    5.     processEngine.getTaskService().completeTask(taskId);  
    6. }  
     

    4.4.12 设置流程变量

     
    [java] view plain copy
     
    1.        // 设置流程变量  
    2. @Test  
    3. public void testSetVariable() throws Exception {  
    4.     String executionId = "test.150001";  
    5.     processEngine.getExecutionService().setVariable(executionId, "请假天数", 15);  
    6. }  
    [java] view plain copy
     
    1.       // 获取流程变量  
    2. @Test  
    3. public void testGetVariable() throws Exception {  
    4.     String executionId = "test.150001";  
    5. Integer days = (Integer) processEngine.getExecutionService().getVariable(executionId, "请假天数");  
    6.     System.out.println("请假天数 = " + days);  
    7. }  
    [java] view plain copy
     
    1. {  
    2.         ExecutionService executionService = processEngine.getExecutionService();  
    3.         TaskService taskService = processEngine.getTaskService();  
    4.   
    5.         // ============ 设置变量 ========================  
    6.         executionService.setVariable(executionId, name, value); // 设置一个变量  
    7.         executionService.setVariables(executionId, variablesMap); // 设置多个变量  
    8.         taskService.setVariables(taskId, variables); // 设置多个变量  
    9.   
    10.                 executionService.startProcessInstanceByKey(processDefinitionKey, variablesMap);                                 // 启动流程实例时,先设置一些变量  
    11.         taskService.completeTask(taskId, variablesMap); // 真正办理完任务前先设置一些变量  
    12.           
    13.           
    14.         // ============ 获取变量 ========================  
    15.         executionService.getVariable(executionId, variableName); // 获取一个变量  
    16.         executionService.getVariableNames(executionId); // 返回Set<String>,是所有变量的名称集合  
    17.         executionService.getVariables(executionId, variableNames);                                                       //获取多个变量,返回Map<String,Object>,表示指定名称的变量信息  
    18.       
    19.         taskService.getVariable(taskId, variableName);  
    20.         taskService.getVariableNames(taskId);  
    21.         taskService.getVariables(taskId, variableNames);  
    22.     }  


    4.4.13 流程执行

     
    [java] view plain copy
     
    1.        @Test  
    2. public void testProcess() throws Exception {  
    3.     // 部署流程定义  
    4.     InputStream in = this.getClass().getResourceAsStream("test.jpdl.xml");  
    5.     String deploymentId = processEngine.getRepositoryService()//      
    6.             .createDeployment()//  
    7.             .addResourceFromInputStream("test.jpdl.xml", in)//  
    8.             .deploy();  
    9.     System.out.println("部署流程定义完毕:deploymentId = " + deploymentId);  
    10.   
    11.     // 启动流程实例  
    12.     ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test");  
    13.     System.out.println("流程实例启动完毕:processInstanceId = " + pi.getId());  
    14.   
    15.     // 完成第一步“提交申请”的任务,要使用指定的Transition离开当前活动  
    16.     Task task = processEngine.getTaskService()//  
    17.             .createTaskQuery()// 获取本流程实例中当前情况下仅有的一个任务  
    18.             .processInstanceId(pi.getId())//  
    19.             .uniqueResult();  
    20.   
    21.     String transitionName1 = "to 部门经理审批";  
    22.     String transitionName2 = "to 总经理审批";  
    23.     processEngine.getTaskService().completeTask(task.getId(), transitionName2);                                     // 使用指定名称的Transition离开本活动  
    24. }  
     

    4.4.14 分配任务

     
    [java] view plain copy
     
    1. public class AssignmentHandlerImpl implements AssignmentHandler {  
    2.   
    3.     // 计算此任务的办理人,并分配任务  
    4.     @Override  
    5.     public void assign(Assignable assignable, OpenExecution execution) throws Exception {  
    6.         System.out.println("---> AssignmentHandlerImpl.assign()");  
    7.         // 计算办理人  
    8.         String userId = "李经理--";  
    9.   
    10.         // 分配个人任务  
    11.         assignable.setAssignee(userId); // 指定个人任务的办理人  
    12.   
    13.         // // 分配组任务  
    14.         // assignable.addCandidateUser("小A"); // 添加一个候选人(组任务)  
    15.         // assignable.addCandidateUser("小B"); // 添加一个候选人(组任务)  
    16.         // assignable.addCandidateUser("小C"); // 添加一个候选人(组任务)  
    17.     }  
    18.   
    19. }  

    4.4.15 组任务与分配

     
    [java] view plain copy
     
    1. public class ProcessTest {  
    2.   
    3.     private static ProcessEngine processEngine = Configuration.getProcessEngine();  
    4.   
    5.     @Test  
    6.     public void testProcess() throws Exception {  
    7.         // 部署流程定义  
    8.         InputStream in = this.getClass().getResourceAsStream("test.jpdl.xml");  
    9.         String deploymentId = processEngine.getRepositoryService()//      
    10.                 .createDeployment()//  
    11.                 .addResourceFromInputStream("test.jpdl.xml", in)//  
    12.                 .deploy();  
    13.         System.out.println("部署流程定义完毕:deploymentId = " + deploymentId);  
    14.   
    15.         // 启动流程实例  
    16.         Map<String, Object> variables = new HashMap<String, Object>();  
    17.         variables.put("manager", "王经理");  
    18.         variables.put("userIds", "小A,小B,小C,小D");  
    19.     ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test", variables);  
    20.         System.out.println("流程实例启动完毕:processInstanceId = " + pi.getId());  
    21.     }  
    22.   
    23.     // 查询组任务列表  
    24.     @Test  
    25.     public void testFindMyGroupTaskList() throws Exception {  
    26.         String userId = "王工程师";  
    27.         // String userId = "赵工程师";  
    28.         // 查询  
    29.         // List<Task> list = processEngine.getTaskService().findGroupTasks(userId);  
    30.         // 分页  
    31.         List<Task> list = processEngine.getTaskService()//  
    32.                 .createTaskQuery()//  
    33.                 .candidate(userId)// 指定候选人,这是查询组任务  
    34.                 .page(0, 100)// 分页  
    35.                 .list();  
    36.   
    37.         // 显示  
    38.         System.out.println("====== " + userId + "的个人任务列表 ======");  
    39.         for (Task task : list) {  
    40.             System.out.println("id=" + task.getId()//  
    41.                     + ", name=" + task.getName()//  
    42.                     + ", assignee=" + task.getAssignee()//  
    43.                     + ", createTime=" + task.getCreateTime()//  
    44.                     + ", executionId=" + task.getExecutionId());  
    45.         }  
    46.     }  
    47.   
    48.     // 拾取任务  
    49.     @Test  
    50.     public void testTakeTask() throws Exception {  
    51.         String taskId = "310009";  
    52.         String userId = "王工程师";  
    53.         processEngine.getTaskService().takeTask(taskId, userId);  
    54.     }  
    55.   
    56.     // 查询个人任务列表  
    57.     @Test  
    58.     public void testFindMyPersonalTaskList() throws Exception {  
    59.         String userId = "王工程师";  
    60.   
    61.         // 查询  
    62.         // List<Task> list = processEngine.getTaskService().findPersonalTasks(userId);  
    63.         // 分页  
    64.         List<Task> list = processEngine.getTaskService()//  
    65.                 .createTaskQuery()//  
    66.                 .assignee(userId)// 指定办理人条件  
    67.                 .page(0, 100)// 分页  
    68.                 .list();  
    69.   
    70.         // 显示  
    71.         System.out.println("====== " + userId + "的个人任务列表 ======");  
    72.         for (Task task : list) {  
    73.             System.out.println("id=" + task.getId()//  
    74.                     + ", name=" + task.getName()//  
    75.                     + ", assignee=" + task.getAssignee()//  
    76.                     + ", createTime=" + task.getCreateTime()//  
    77.                     + ", executionId=" + task.getExecutionId());  
    78.         }  
    79.     }  
    80.   
    81.     // 直接指定任务的办理人  
    82.     @Test  
    83.     public void testAssignTask() throws Exception {  
    84.         String taskId = "310009";  
    85.         // String userId = null; // 退回到组任务列表  
    86.         String userId = "赵工程师";  
    87.         processEngine.getTaskService().assignTask(taskId, userId);  
    88.     }  
    89.   
    90. }  
     
    如需转载;请注明原文出处谢谢合作!
  • 相关阅读:
    JQuery帮助文档整理
    将table信息导出到excel
    jquery 选择器
    程序不小心出现死锁的解决方法
    兼容IE firefox 的全英文自动换行
    第三周2
    Jquery操作Select集锦
    Silverlight初学之:如果调用Silverlight项目中不同的控件
    【转载】很好的解决了asp.net页面ViewState过大的问题
    js得到url的各个部分【转】
  • 原文地址:https://www.cnblogs.com/bojuetech/p/6065577.html
Copyright © 2011-2022 走看看