JBPM笔记-基础范例

来源:互联网 发布:英语美文软件下载 编辑:程序博客网 时间:2024/05/16 09:39

1、节点含义

<?xml version="1.0" encoding="UTF-8"?><process-definition  xmlns="urn:jbpm.org:jpdl-3.2"  name="example001">   <start-state name="start">      <transition name="" to="state1"></transition>   </start-state>     <state name="state1">      <transition name="" to="node1"></transition>   </state>      <node name="node1">      <transition name="" to="state2"></transition>   </node>      <state name="state2">      <transition name="" to="task1"></transition>   </state>      <task-node name="task1">      <transition name="tobf" to="end1"></transition>   </task-node>    <end-state name="end1"></end-state></process-definition>

JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());token.signal();logger.info("NodeName:"+token.getNode().getName());token.signal();logger.info("NodeName:"+token.getNode().getName());

显示结果如下:

NodeName:state1
NodeName:state2
NodeName:end1


总结:

node、state、task节点分别为node、等待节点、任务节点。

进过node、task-node不需要singal就往下走,所以没有显示他们的名称,state节点必须singal才往下走。



二、ActionHandler、设置工作参与者以及获取工作路由


<?xml version="1.0" encoding="UTF-8"?><process-definition  xmlns="urn:jbpm.org:jpdl-3.2"  name="example002">   <start-state name="start">      <transition name="" to="state1"></transition>   </start-state>     <state name="state1">      <transition name="" to="node1"></transition>   </state>      <node name="node1">      <action class="jbpm.java.handler.example.TestAction"></action>      <transition name="" to="state2"></transition>   </node>      <state name="state2">      <transition name="" to="task1"></transition>   </state>      <task-node name="task1">       <task>         <assignment actor-id="#{user}"></assignment>      </task>      <transition name="tobf" to="end1"></transition>   </task-node>    <end-state name="end1"></end-state></process-definition>


TestAction.java

public class TestAction implements ActionHandler {private static final long serialVersionUID = 1196655833977006482L;@Overridepublic void execute(ExecutionContext executionContext) throws Exception {System.out.println("通过Action类来解决问题!!!");}}

JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);processInstance.getContextInstance().setVariable("user", "用户");Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());token.signal();logger.info("NodeName:"+token.getNode().getName());token.signal();logger.info("NodeName:"+token.getNode().getName());token.signal();logger.info("NodeName:"+token.getNode().getName());TaskInstance ti = (TaskInstance)processInstance.getTaskMgmtInstance().getTaskInstances().iterator().next();System.out.println("现在工作的参与者是"+ti.getActorId());//获取该工作的路由List<Transition> tns = ti.getTask().getTaskNode().getLeavingTransitions();for(Transition tn : tns) {System.out.println("该工作的所有路由"+tn.getName());}

输出结果:

NodeName:state1
通过Action类来解决问题!!!
NodeName:node1
NodeName:state2
NodeName:task1
现在工作的参与者是用户
该工作的所有路由tobf


三、beanShell脚本、Assignment应用


<?xml version="1.0" encoding="UTF-8"?><process-definition  xmlns="urn:jbpm.org:jpdl-3.2"  name="example003"><start-state name="start"><transition name="" to="task1"></transition></start-state>   <task-node name="task1"><task>                      <assignment class="jbpm.java.handler.example.TestAssignment"></assignment><assignment actor-id="用户001"/></task><event type="node-enter"><script>print("当前节点对象的ID:"+token.getId());contextInstance = executionContext.getContextInstance();print("流程变量param的值:"+contextInstance.getVariable("param"));print("直接获取变量值:"+param); </script></event><transition name="" to="end1"></transition></task-node>   <end-state name="end1"></end-state>   </process-definition>


TestAssignment.java


public class TestAssignment implements AssignmentHandler{private static final long serialVersionUID = 1443420479356838909L;@Overridepublic void assign(Assignable assignable, ExecutionContext executionContext) throws Exception {assignable.setActorId("用户001");}}


JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);ContextInstance contextInstance = processInstance.getContextInstance();contextInstance.setVariable("param", "参数param值");Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());token.signal();logger.info("NodeName:"+token.getNode().getName());

结果如下:

当前节点对象的ID:23
流程变量param的值:param的值
直接获取变量值:param的值
 NodeName:task1
NodeName:end1
现在工作的参与者是用户001


四、fork join 节点

discriminator = true 经过一个节点,则结束。  一般开发不使用。

默认情况下join会等到所有从fork上生成的子token都到达join节点时,才会继续向下。


<?xml version="1.0" encoding="UTF-8"?><process-definition xmlns="urn:jbpm.org:jpdl-3.2"  name="example004">     <start-state name="start">      <transition name="" to="fork1"></transition>   </start-state>      <fork name="fork1">      <script>         <variable name="transNames" access="write"></variable>         <expression>            transNames = new ArrayList();            if(param>100){               transNames.add("tr1");               transNames.add("tr2");            }else{               transNames.add("tr3");               transNames.add("tr4");            }         </expression>      </script>      <transition name="tr1" to="node1"></transition>      <transition name="tr2" to="node2"></transition>      <transition name="tr3" to="node3"></transition>      <transition name="tr4" to="node4"></transition>   </fork>         <node name="node1">      <event type="node-enter">         <script>            print("进入第一个节点");         </script>      </event>      <transition name="" to="join1"></transition>   </node>      <node name="node2">      <event type="node-enter">         <script>            print("进入第二个节点");         </script>      </event>      <transition name="" to="join1"></transition>   </node>      <node name="node3">      <event type="node-enter">         <script>            print("进入第三个节点");         </script>      </event>      <transition name="" to="join1"></transition>   </node>         <node name="node4">      <event type="node-enter">         <script>            print("进入第四个节点");         </script>      </event>      <transition name="" to="join1"></transition>   </node>       <join name="join1">      <transition name="" to="end1"></transition>   </join>         <end-state name="end1">      <event type="node-enter">         <script>          print("结束操作");        </script>      </event>   </end-state></process-definition>

JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);processInstance.getContextInstance().setVariable("param", new Integer(11));Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());

结果如下:


进入第三个节点
进入第四个节点
结束操作
NodeName:end1


四、Decision节点  

定义流程走向节点,在本节点上添加多个Transtion,和Fork相反,只能在多个Transition内选择一个。

A:未指定decision线路。

<?xml version="1.0" encoding="UTF-8"?><process-definition xmlns="urn:jbpm.org:jpdl-3.2"  name="example005"><start-state name="start">      <transition name="" to="decision1"></transition>   </start-state>   <decision name="decision1">      <transition name="tr1" to="node1"></transition>      <transition name="tr2" to="node2"></transition>      <transition name="tr3" to="node3"></transition>   </decision>   <node name="node1">     <event type="node-enter">        <script>          print("进入第一个节点");        </script>     </event>      <transition name="" to="end1"></transition>   </node>   <node name="node2">   <event type="node-enter">        <script>          print("进入第二个节点");        </script>     </event>      <transition name="" to="end1"></transition>   </node>   <node name="node3">   <event type="node-enter">        <script>          print("进入第三个节点");        </script>     </event>      <transition name="" to="end1"></transition>   </node>   <end-state name="end1">      <event type="node-enter">         <script>          print("结束操作");        </script>      </event>   </end-state></process-definition>

String processName = (String)Persistence.getVariable("processName");logger.info("processName:"+processName);JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());


只要经过一个节点,就可以继续向下流转。没指定默认进入第一个。

结果如下:
进入第一个节点
结束操作
NodeName:end1

end

B:通过表达式变量程序内指定方式指定decision线路

<?xml version="1.0" encoding="UTF-8"?><process-definition xmlns="urn:jbpm.org:jpdl-3.2"  name="example005"><start-state name="start">      <transition name="" to="decision1"></transition>   </start-state>   <decision name="decision1" expression="#{tname}">      <transition name="tr1" to="node1"></transition>      <transition name="tr2" to="node2"></transition>      <transition name="tr3" to="node3"></transition>   </decision>   <node name="node1">     <event type="node-enter">        <script>          print("进入第一个节点");        </script>     </event>      <transition name="" to="end1"></transition>   </node>   <node name="node2">   <event type="node-enter">        <script>          print("进入第二个节点");        </script>     </event>      <transition name="" to="end1"></transition>   </node>   <node name="node3">   <event type="node-enter">        <script>          print("进入第三个节点");        </script>     </event>      <transition name="" to="end1"></transition>   </node>   <end-state name="end1">      <event type="node-enter">         <script>          print("结束操作");        </script>      </event>   </end-state></process-definition>

JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);processInstance.getContextInstance().setVariable("tname", "tr2");Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());

结果:

进入第二个节点
结束操作
NodeName:end1
end

C:通过DecisionHandler方式指定decision线路

<?xml version="1.0" encoding="UTF-8"?><process-definition xmlns="urn:jbpm.org:jpdl-3.2"  name="example005"><start-state name="start">      <transition name="" to="decision1"></transition>   </start-state>   <decision name="decision1">      <handler class="jbpm.java.handler.example.TestDecision"/>      <transition name="tr1" to="node1"></transition>      <transition name="tr2" to="node2"></transition>      <transition name="tr3" to="node3"></transition>   </decision>   <node name="node1">     <event type="node-enter">        <script>          print("进入第一个节点");        </script>     </event>      <transition name="" to="end1"></transition>   </node>   <node name="node2">   <event type="node-enter">        <script>          print("进入第二个节点");        </script>     </event>      <transition name="" to="end1"></transition>   </node>   <node name="node3">   <event type="node-enter">        <script>          print("进入第三个节点");        </script>     </event>      <transition name="" to="end1"></transition>   </node>   <end-state name="end1">      <event type="node-enter">         <script>          print("结束操作");        </script>      </event>   </end-state></process-definition>

TestDecision.java


public class TestDecision implements DecisionHandler {private static final long serialVersionUID = -9083605280987838663L;@Overridepublic String decide(ExecutionContext executionContext) throws Exception {return "tr3";}}

JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());

结果:

进入第三个节点
结束操作
NodeName:end1
end


五、根据参与者actor-id取到对应任务、根据任务ID取得实例


<?xml version="1.0" encoding="UTF-8"?><process-definition xmlns="urn:jbpm.org:jpdl-3.2"  name="example008"><start-state name="start">      <transition name="" to="task1"></transition>   </start-state>   <task-node name="task1">      <event type="task-create">        <script>          print("触发了task-create事件");        </script>      </event>      <event type="task-start">        <script>          print("触发了task-start事件");        </script>      </event>      <event type="task-assign">        <script>          print("触发了task-assign事件");        </script>      </event>      <event type="task-end">        <script>          print("触发了task-end事件");        </script>      </event>      <task>         <assignment actor-id="admin001"></assignment>      </task>      <transition name="" to="end1"></transition>   </task-node>      <end-state name="end1"></end-state></process-definition>

JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());//根据参与者actor-id取到对应任务List<TaskInstance> taskInstance = jbpmContext.getTaskMgmtSession().findTaskInstances("admin001");for(TaskInstance ti : taskInstance){logger.info("actor-id:"+ti.getName());}
输出结果:

触发了task-create事件
触发了task-assign事件
NodeName:task1
actor-id:task1

JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());//根据任务ID取得实例TaskInstance taskInstance = jbpmContext.loadTaskInstance(taskInstanceId);logger.info("actor-id:"+taskInstance.getName());/


输出结果如下:

触发了task-create事件
触发了task-assign事件
NodeName:task1
actor-id:task1


六、Swimlane方式

用于处理一个流程中多个任务节点由同一个人或者角色来完成。


<?xml version="1.0" encoding="UTF-8"?><process-definition xmlns="urn:jbpm.org:jpdl-3.2"  name="example009"><swimlane name="user"><assignment actor-id="#{userId}"></assignment></swimlane><start-state name="start">      <transition name="" to="task1"></transition>   </start-state>   <task-node name="task1">      <event type="task-create">        <script>          print("触发了task-create事件");        </script>      </event>      <event type="task-start">        <script>          print("触发了task-start事件");        </script>      </event>      <event type="task-assign">        <script>          print("触发了task-assign事件");        </script>      </event>      <event type="task-end">        <script>          print("触发了task-end事件");        </script>      </event>      <task swimlane="user"/>            <transition name="" to="end1"></transition>   </task-node>      <end-state name="end1"></end-state></process-definition>

JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);processInstance.getContextInstance().setVariable("userId", "admin002");Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());List<TaskInstance> taskInstance = jbpmContext.getTaskMgmtSession().findTaskInstances("admin002");for(TaskInstance ti : taskInstance){logger.info("actor-id:"+ti.getName());}

输出结果:

触发了task-create事件
触发了task-assign事件
NodeName:task1
actor-id:task1




七、pooled-actors方式 

一个任务直接分配给多个参与者,多个参与者用逗号隔开。

例如:提交给一个部门,该部门的人都能看到,其中一个人处理就可以了。

这种方式只能静态分配,不能动态分配。所以适用范围有限。


<?xml version="1.0" encoding="UTF-8"?><process-definition xmlns="urn:jbpm.org:jpdl-3.2"  name="example010"><start-state name="start">      <transition name="" to="task1"></transition>   </start-state>   <task-node name="task1">      <event type="task-create">        <script>          print("触发了task-create事件");        </script>      </event>      <event type="task-start">        <script>          print("触发了task-start事件");        </script>      </event>      <event type="task-assign">        <script>          print("触发了task-assign事件");        </script>      </event>      <event type="task-end">        <script>          print("触发了task-end事件");        </script>      </event>      <task>      <assignment pooled-actors="admin001,admin002,admin003"></assignment>      </task>            <transition name="" to="end1"></transition>   </task-node>      <end-state name="end1"></end-state></process-definition>

JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());List<TaskInstance> taskInstance = jbpmContext.getTaskMgmtSession().findPooledTaskInstances("admin001");for(TaskInstance ti : taskInstance){logger.info("pooled-actors:"+ti.getName());}

输出结果如下:


触发了task-create事件
NodeName:task1
pooled-actors:task1


七、发送mail提醒

A、建立邮件服务。

下载james-2.3.2,解压。进入dos命令行模式,进入C:\james-2.3.2\bin,执行run.bat




例图所示邮件服务器启动完毕,请不要关闭dos窗口。

pop3,smtp,等信息显示如上。


再打开新的dos窗口。


输入telnet localhost 4555



提示输入用户名密码:都是root

之后输入help,可以看到命令帮助。


输入 adduser   adminsender   123456   

新增一个用户以及密码。新增完毕之后即可关闭此窗口,或者输入quit退出。


B、程序配置。

把jbpm-jpdl-3.2.3中的两个jar文件activation.jar、mail.jar放置工程中。

<?xml version="1.0" encoding="UTF-8"?><process-definition  xmlns=""  name="example011"><start-state name="start-state1"><transition to="task-node1"></transition></start-state><task-node name="task-node1"><task name="notifyTask" notify="true"><assignment actor-id="adminsender"></assignment></task><transition to="end-state1"></transition></task-node><end-state name="end-state1"></end-state></process-definition>


或者使用下面流程文件:

<?xml version="1.0" encoding="UTF-8"?><process-definition  xmlns=""  name="example012"><start-state name="start-state1"><transition to="task-node1"></transition></start-state><task-node name="task-node1"><task name="notifyTask"><assignment actor-id="adminsender"/><event type="task-assign"><mail template="task-assign"/></event></task><transition to="end-state1"></transition></task-node><end-state name="end-state1"></end-state></process-definition>



注意 xmlns="" ,里面暂时为空。不能放入urn:jbpm.org:jpdl-3.2,否则会在部署的时候提示org.jbpm.jpdl.JpdlException: [[ERROR] line 12: cvc-complex-type.3.2.2: Attribute 'notify' is not allowed to appear in element 'task'.]

原因暂时不清数,不过去掉,即可正常部署。


建立MailResolver.java文件

package jbpm.java.mail;import org.jbpm.mail.AddressResolver;public class MailResolver implements AddressResolver{private static final long serialVersionUID = 3634448991562190346L;@Overridepublic Object resolveAddress(String actorId) {if(actorId.equals("adminsender")){return "adminsender@localhost";}else{return "adminsender@localhost";}}}

修改jbpm.cfg.xml,加入如下内容:

  <string name="resource.mail.templates" value="jbpm.mail.templates.xml"/>  <string name="jbpm.mail.smtp.host" value="localhost"/>  <string name="jbpm.mail.smtp.port" value="25"/>  <bean name="jbpm.mail.address.resolver" class="jbpm.java.mail.MailResolver" singleton="true"/>  <string name="jbpm.mail.from.address" value="adminsender@localhost"/>  <string name="jbpm.mail.smtp.auth" value="true"/>

部署xml文件。执行

JbpmContext jbpmContext = getJbpmContext();GraphSession graphSession=jbpmContext.getGraphSession();ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName);ProcessInstance processInstance = new ProcessInstance(processDefinition);Token token = processInstance.getRootToken();token.signal();logger.info("NodeName:"+token.getNode().getName());

提示

java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream错误。


主要原因是javax.mail和javax.activation这两个包已经在javaEE5当中属于基础包了,但是里面的方法与现在jbpm提供的的mail.jar和activation.jar有一些出入


X:/Program Files/MyEclipse 6.5/myeclipse/eclipse/plugins/com.genuitec.eclipse.j2eedt.core_6.5.0.zmyeclipse650200806/data/libraryset/EE_5


这个路径里,可以看到javaee.jar,用rar把这个文件打开,然后进到javax文件夹里,删除mail.jar和activation.jar。注意备份。


之后执行,则通过。


八、任务调度


原创粉丝点击