日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Jbpm 流程节点

發布時間:2025/3/17 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Jbpm 流程节点 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、Node節點
Node節點是一個自動完成節點,如果沒有在Node節點上定義Action,流程達到Node節點后不會停留,而是繼續往下執行到Node節點的下一個節點。利用之前的Helloworld例子,我們在Node節點上加上一個Action(Action的執行是在node-enter之后node-leave之前)
Xml代碼 ?
  • <node?name="node1">??
  • ????<action?class="com.royzhou.action.NodeAction"></action>??
  • ????<transition?to="state1"></transition>??
  • </node>??
  • <node name="node1"><action class="com.royzhou.action.NodeAction"></action><transition to="state1"></transition></node>
    Action類如下:
    Java代碼 ?
  • package?com.royzhou.action; ??
  • ??
  • import?org.jbpm.graph.def.ActionHandler; ??
  • import?org.jbpm.graph.exe.ExecutionContext; ??
  • ??
  • public?class?NodeAction?implements?ActionHandler?{ ??
  • ????public?void?execute(ExecutionContext?executionContext)?throws?Exception?{ ??
  • ????????System.out.println("node?action……………………"); ??
  • ????} ??
  • }??
  • package com.royzhou.action;import org.jbpm.graph.def.ActionHandler; import org.jbpm.graph.exe.ExecutionContext;public class NodeAction implements ActionHandler {public void execute(ExecutionContext executionContext) throws Exception {System.out.println("node action……………………");} }
    測試類如下:
    Java代碼 ?
  • package?com.royzhou.test; ??
  • ??
  • import?java.io.FileInputStream; ??
  • import?java.io.FileNotFoundException; ??
  • import?java.util.zip.ZipInputStream; ??
  • ??
  • import?org.jbpm.JbpmConfiguration; ??
  • import?org.jbpm.JbpmContext; ??
  • import?org.jbpm.graph.def.ProcessDefinition; ??
  • import?org.jbpm.graph.exe.ProcessInstance; ??
  • import?org.jbpm.graph.exe.Token; ??
  • ??
  • public?class?HelloWorldDB?{ ??
  • ????public?static?void?deploy()?throws?FileNotFoundException?{ ??
  • ????????JbpmConfiguration?jbpmConfiguration?=?JbpmConfiguration.getInstance(); ??
  • ????????JbpmContext?jbpmContext?=?jbpmConfiguration.createJbpmContext(); ??
  • ????????try?{ ??
  • ????????????FileInputStream?fis?=?new?FileInputStream("F:/workspace/jbpm-test/src/main/jpdl/helloworld/helloworld.zip?"); ??
  • ????????????ZipInputStream?zis?=?new?ZipInputStream(fis); ??
  • ????????????ProcessDefinition?processDefinition?=?ProcessDefinition.parseParZipInputStream(zis); ??
  • ????????????jbpmContext.deployProcessDefinition(processDefinition); ??
  • ????????????fis.close(); ??
  • ????????????zis.close(); ??
  • ????????}?catch(Exception?e)?{ ??
  • ????????????e.printStackTrace(); ??
  • ????????}?finally?{ ??
  • ????????????jbpmContext.close(); ??
  • ????????} ??
  • ????} ??
  • ???? ??
  • ????public?static?void?main(String[]?args)?throws?FileNotFoundException?{ ??
  • ????????HelloWorldDB.deploy(); ??
  • ????????JbpmConfiguration?jbpmConfiguration?=?JbpmConfiguration.getInstance(); ??
  • ????????JbpmContext?jbpmContext?=?jbpmConfiguration.createJbpmContext(); ??
  • ????????jbpmContext.setActorId("royzhou"); ??
  • ????????//獲取最新版本的流程定義對象 ??
  • ????????ProcessDefinition?processDefinition?=?jbpmContext.getGraphSession().findLatestProcessDefinition("helloworld"); ??
  • ????????ProcessInstance?processInstance?=?new?ProcessInstance(processDefinition); ??
  • ????????//得到流程令牌 ??
  • ????????Token?token?=?processInstance.getRootToken(); ??
  • ???????? ??
  • ????????//打印流程當前所處節點 ??
  • ????????System.out.println("1:流程現在所處節點:"?+?token.getNode().getName()); ??
  • ???????? ??
  • ????????//觸發流程流轉到下一個節點Node ??
  • ????????token.signal(); ??
  • ???????? ??
  • ????????/** ?
  • ?????????*?注意因為Node節點設置Action ?
  • ?????????*?所以流程會停留在Node節點 ?
  • ?????????*/??
  • ????????System.out.println("2:流程現在所處節點:"?+?token.getNode().getName()); ??
  • ???????? ??
  • ????????//觸發流程流轉到下一個節點State ??
  • ????????token.signal(); ??
  • ????????System.out.println("3:流程現在所處節點:"?+?token.getNode().getName()); ??
  • token.signal(); ??
  • ????????System.out.println("4:流程現在所處節點:"?+?token.getNode().getName()); ??
  • ????????System.out.println("流程狀態是否結束:"?+?token.getProcessInstance().hasEnded()); ??
  • ????????jbpmContext.close(); ??
  • ????} ??
  • }??
  • package com.royzhou.test;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.zip.ZipInputStream;import org.jbpm.JbpmConfiguration; import org.jbpm.JbpmContext; import org.jbpm.graph.def.ProcessDefinition; import org.jbpm.graph.exe.ProcessInstance; import org.jbpm.graph.exe.Token;public class HelloWorldDB {public static void deploy() throws FileNotFoundException {JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();try {FileInputStream fis = new FileInputStream("F:/workspace/jbpm-test/src/main/jpdl/helloworld/helloworld.zip ");ZipInputStream zis = new ZipInputStream(fis);ProcessDefinition processDefinition = ProcessDefinition.parseParZipInputStream(zis);jbpmContext.deployProcessDefinition(processDefinition);fis.close();zis.close();} catch(Exception e) {e.printStackTrace();} finally {jbpmContext.close();}}public static void main(String[] args) throws FileNotFoundException {HelloWorldDB.deploy();JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();jbpmContext.setActorId("royzhou");//獲取最新版本的流程定義對象ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition("helloworld");ProcessInstance processInstance = new ProcessInstance(processDefinition);//得到流程令牌Token token = processInstance.getRootToken();//打印流程當前所處節點System.out.println("1:流程現在所處節點:" + token.getNode().getName());//觸發流程流轉到下一個節點Nodetoken.signal();/*** 注意因為Node節點設置Action* 所以流程會停留在Node節點*/System.out.println("2:流程現在所處節點:" + token.getNode().getName());//觸發流程流轉到下一個節點Statetoken.signal();System.out.println("3:流程現在所處節點:" + token.getNode().getName()); token.signal();System.out.println("4:流程現在所處節點:" + token.getNode().getName());System.out.println("流程狀態是否結束:" + token.getProcessInstance().hasEnded());jbpmContext.close();} }
    測試結果如下:(驗證了在Node上設置Action的時候,流程處于等待狀態)
    1:流程現在所處節點:start-state1
    node action……………………
    2:流程現在所處節點:node1
    3:流程現在所處節點:state1
    4:流程現在所處節點:end-state1
    流程狀態是否結束:true

    2、State節點
    State節點屬性類似Node,不過當流程流轉到State節點時就會停下來,直到外部向其發送流轉的命令,如signal().

    3、Task-Node
    Task Node節點在Jbpm中是很重要的一個節點,可以用來添加任務,產生任務實例。一個Task Node 可以定義多個Task,為Task分配執行人等等。下面我們通過一個例子來解釋Task Node。
    Xml代碼 ?
  • ????<?xml?version="1.0"?encoding="UTF-8"?>??
  • ??
  • <process-definition??xmlns="urn:jbpm.org:jpdl-3.2"??name="tasknode">??
  • ????<start-state?name="start-state1">??
  • ????????<transition?to="task-node1"></transition>??
  • ????</start-state>??
  • ????<task-node?name="task-node1">??
  • ????????<task?name="mytask">??
  • ????????????<assignment?actor-id="royzhou"></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="urn:jbpm.org:jpdl-3.2" name="tasknode"><start-state name="start-state1"><transition to="task-node1"></transition></start-state><task-node name="task-node1"><task name="mytask"><assignment actor-id="royzhou"></assignment></task><transition to="end-state1"></transition></task-node><end-state name="end-state1"></end-state> </process-definition>
    上面流程文件定義了一個Task Node ,在Task Node下面定義了一個Task節點,分配給了royzhou這個人(實際開發中的任務分配會更加復雜)
    接下來我們開始寫測試類:
    Java代碼 ?
  • ????package?com.royzhou.test; ??
  • ??
  • import?java.io.FileInputStream; ??
  • import?java.io.FileNotFoundException; ??
  • import?java.util.zip.ZipInputStream; ??
  • ??
  • import?org.jbpm.JbpmConfiguration; ??
  • import?org.jbpm.JbpmContext; ??
  • import?org.jbpm.graph.def.ProcessDefinition; ??
  • import?org.jbpm.graph.exe.ProcessInstance; ??
  • import?org.jbpm.graph.exe.Token; ??
  • ??
  • public?class?TaskNode?{ ??
  • ???? ??
  • ????public?static?void?deploy()?throws?FileNotFoundException?{ ??
  • ????????JbpmConfiguration?jbpmConfiguration?=?JbpmConfiguration.getInstance(); ??
  • ????????JbpmContext?jbpmContext?=?jbpmConfiguration.createJbpmContext(); ??
  • ????????try?{ ??
  • ????????????FileInputStream?fis?=?new?FileInputStream("F:/workspace/jbpm-test/src/main/jpdl/tasknode/tasknode.zip"); ??
  • ????????????ZipInputStream?zis?=?new?ZipInputStream(fis); ??
  • ????????????ProcessDefinition?processDefinition?=?ProcessDefinition.parseParZipInputStream(zis); ??
  • ????????????jbpmContext.deployProcessDefinition(processDefinition); ??
  • ????????????fis.close(); ??
  • ????????????zis.close(); ??
  • ????????}?catch(Exception?e)?{ ??
  • ????????????e.printStackTrace(); ??
  • ????????}?finally?{ ??
  • ????????????jbpmContext.close(); ??
  • ????????} ??
  • ????} ??
  • ???? ??
  • ????public?static?void?main(String[]?args)?throws?FileNotFoundException?{ ??
  • ????????TaskNode.deploy(); ??
  • ????????JbpmConfiguration?jbpmConfiguration?=?JbpmConfiguration.getInstance(); ??
  • ????????JbpmContext?jbpmContext?=?jbpmConfiguration.createJbpmContext(); ??
  • ????????ProcessDefinition?processDefinition?=?jbpmContext.getGraphSession().findLatestProcessDefinition("tasknode"); ??
  • ????????ProcessInstance?processInstance?=?new?ProcessInstance(processDefinition); ??
  • ????????Token?token?=?processInstance.getRootToken(); ??
  • ????????token.signal(); ??
  • ????????System.out.println("流程現在所處節點:"?+?token.getNode().getName()); ??
  • ????????jbpmContext.close(); ??
  • ????} ??
  • }??
  • package com.royzhou.test;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.zip.ZipInputStream;import org.jbpm.JbpmConfiguration; import org.jbpm.JbpmContext; import org.jbpm.graph.def.ProcessDefinition; import org.jbpm.graph.exe.ProcessInstance; import org.jbpm.graph.exe.Token;public class TaskNode {public static void deploy() throws FileNotFoundException {JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();try {FileInputStream fis = new FileInputStream("F:/workspace/jbpm-test/src/main/jpdl/tasknode/tasknode.zip");ZipInputStream zis = new ZipInputStream(fis);ProcessDefinition processDefinition = ProcessDefinition.parseParZipInputStream(zis);jbpmContext.deployProcessDefinition(processDefinition);fis.close();zis.close();} catch(Exception e) {e.printStackTrace();} finally {jbpmContext.close();}}public static void main(String[] args) throws FileNotFoundException {TaskNode.deploy();JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition("tasknode");ProcessInstance processInstance = new ProcessInstance(processDefinition);Token token = processInstance.getRootToken();token.signal();System.out.println("流程現在所處節點:" + token.getNode().getName());jbpmContext.close();} }
    后臺打印結果:
    流程現在所處節點:task-node1
    查看jbpm_taskinstance表看到一個名叫mytask的任務,指定給了royzhou說明我們的任務創建成功了。
    Task Node有幾個比較重要的屬性:
    Signal:
    last:最后一個完成之后繼續往下流轉,如果沒有任務被創建直接流轉到下一節點
    last-wait:最后一個完成之后繼續往下流轉,如果沒有任務被創建處于等待狀態
    first:只要有一個完成就繼續往下流轉,如果沒有任務被創建直接流轉下一個節點
    first-wait:只要一個完成就繼續往下流轉,如果沒有任務被創建則處于等待狀態
    never:必須顯示調用processInstance.signal()才繼續流轉
    unsynchronized:不停留,直接流轉到下個節點

    task-creates:流程流轉到這個節點上時是不是自動創建任務,默認是true。通過設置為false,配合其他事件我們可以實現會簽的功能。

    4、Start節點
    Start節點在每個流程中有且只能有一個。Start中可以配置Task,但是 配置在Start節點中的task不會調用任務分配機制。這點是不同于Task Node的。。。。

    5、fork和join節點
    二者是成對出現的。Fork節點可以將流程拆分成多條并行也就是將Token拆分成多個子Token,到join節點的時候再匯聚成一個Token繼續往下執行
    一般來說,在經過fork節點之后,必須等待每個子token都走完才會通過join節點繼續往下走,但是我們可以通過修改join節點的discriminator屬性來,設置為true之后只要有一個子token到達join節點,就會往下流轉。不過這樣做產生的一個影響就是其他沒有結束的子token上的任務實例依然存在且處于等待狀態,任務參與者仍然可以處理這些任務。因此,在設置join節點的discriminator為true時,我們還需要手動結束掉其他分支上的任務實例。
    在fork節點中,我們可以設定條件來選擇只走滿足條件的分支。主要是通過之前提到的beanshell腳本來實現。舉例說明一下這個實現:
    流程定義由一個start節點,一個end節點,一對fork/join節點以及分支中的四個node節點組成,流程定義的xml文件如下:
    Xml代碼 ?
  • <?xml?version="1.0"?encoding="UTF-8"?>??
  • <process-definition??xmlns="urn:jbpm.org:jpdl-3.2"??name="forkjoin">??
  • ????<start-state?name="start-state1">??
  • ????????<transition?to="fork1"></transition>??
  • ????</start-state>??
  • ????<fork?name="fork1">??
  • ????????<script>??
  • ????????????<variable?name="forkTransition"?access="write"></variable>??
  • ????????????<expression>??
  • ????????????????forkTransition?=?new?ArrayList(); ??
  • ????????????????if(param?&gt;?1000)?{ ??
  • ????????????????????forkTransition.add("to?node1"); ??
  • ????????????????????forkTransition.add("to?node2"); ??
  • ????????????????}?else?{ ??
  • ????????????????????forkTransition.add("to?node3"); ??
  • ????????????????????forkTransition.add("to?node4"); ??
  • ????????????????} ??
  • ????????????</expression>??
  • ????????</script>??
  • ????????<transition?to="node1"?name="to?node1"></transition>??
  • ????????<transition?to="node2"?name="to?node2"></transition>??
  • ????????<transition?to="node3"?name="to?node3"></transition>??
  • ????????<transition?to="node4"?name="to?node4"></transition>??
  • ????</fork>??
  • ????<join?name="join1">??
  • ????????<transition?to="end-state1"></transition>??
  • ????</join>??
  • ????<node?name="node1">??
  • ????????<event?type="node-enter">??
  • ????????????<script>??
  • ????????????????print(&quot;node1?enter&quot;); ??
  • ????????????</script>??
  • ????????</event>??
  • ????????<transition?to="join1"></transition>??
  • ????</node>??
  • ????<node?name="node2">??
  • ????????<event?type="node-enter">??
  • ????????????<script>??
  • ????????????????print(&quot;node2?enter&quot;); ??
  • ????????????</script>??
  • ????????</event>??
  • ????????<transition?to="join1"></transition>??
  • ????</node>??
  • ????<node?name="node3">??
  • ????????<event?type="node-enter">??
  • ????????????<script>??
  • ????????????????print(&quot;node3?enter&quot;); ??
  • ????????????</script>??
  • ????????</event>??
  • ????????<transition?to="join1"></transition>??
  • ????</node>??
  • ????<node?name="node4">??
  • ????????<event?type="node-enter">??
  • ????????????<script>??
  • ????????????????print(&quot;node4?enter&quot;); ??
  • ????????????</script>??
  • ????????</event>??
  • ????????<transition?to="join1"></transition>??
  • ????</node>??
  • ????<end-state?name="end-state1"></end-state>??
  • </process-definition>??
  • <?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="forkjoin"><start-state name="start-state1"><transition to="fork1"></transition></start-state><fork name="fork1"><script><variable name="forkTransition" access="write"></variable><expression>forkTransition = new ArrayList();if(param &gt; 1000) {forkTransition.add("to node1");forkTransition.add("to node2");} else {forkTransition.add("to node3");forkTransition.add("to node4");}</expression></script><transition to="node1" name="to node1"></transition><transition to="node2" name="to node2"></transition><transition to="node3" name="to node3"></transition><transition to="node4" name="to node4"></transition></fork><join name="join1"><transition to="end-state1"></transition></join><node name="node1"><event type="node-enter"><script>print(&quot;node1 enter&quot;);</script></event><transition to="join1"></transition></node><node name="node2"><event type="node-enter"><script>print(&quot;node2 enter&quot;);</script></event><transition to="join1"></transition></node><node name="node3"><event type="node-enter"><script>print(&quot;node3 enter&quot;);</script></event><transition to="join1"></transition></node><node name="node4"><event type="node-enter"><script>print(&quot;node4 enter&quot;);</script></event><transition to="join1"></transition></node><end-state name="end-state1"></end-state> </process-definition>
    默認情況下,當流程進入fork節點之后會分成四個分支,分別經過Node節點。在上面定義文件中我們在fork節點下做了判斷,如果流程變量param>1000的時候走分支1和分支2,如果小于則走分支3和分支4。
    Xml代碼 ?
  • <script>??
  • ????????????<variable?name="forkTransition"?access="write"></variable>??
  • ????????????<expression>??
  • ????????????????forkTransition?=?new?ArrayList(); ??
  • ????????????????if(param?&gt;?1000)?{ ??
  • ????????????????????forkTransition.add("to?node1"); ??
  • ????????????????????forkTransition.add("to?node2"); ??
  • ????????????????}?else?{ ??
  • ????????????????????forkTransition.add("to?node3"); ??
  • ????????????????????forkTransition.add("to?node4"); ??
  • ????????????????} ??
  • ????????????</expression>??
  • ????????</script>??
  • <script><variable name="forkTransition" access="write"></variable><expression>forkTransition = new ArrayList();if(param &gt; 1000) {forkTransition.add("to node1");forkTransition.add("to node2");} else {forkTransition.add("to node3");forkTransition.add("to node4");}</expression></script>
    注意這里的forkTransition必須是集合類型,它存放的是流程經過fork之后生成的分支名稱。access屬性設置為write表示是寫入流程實例對應的Fork節點,才能生成我們指定的分支。在Expression標簽下是我們做的邏輯處理,通過流程變量param來判斷Fork節點具體要生成那些分支。
    默認我們不為Fork節點添加script,流程到Fork節點時將生成所有transition。一旦設置了script,還必須設置一個變量,如上面的forkTransition寫回流程變量中生成具體的分支。

    測試類如下:(為方便測試沒有將流程發布到數據庫,下面測試例子也是采用相同做法)
    Java代碼 ?
  • package?com.royzhou.test; ??
  • ??
  • import?org.jbpm.graph.def.ProcessDefinition; ??
  • import?org.jbpm.graph.exe.ProcessInstance; ??
  • import?org.jbpm.graph.exe.Token; ??
  • ??
  • public?class?ForkJoin?{ ??
  • ???? ??
  • ????public?static?void?main(String[]?args)?{ ??
  • ????????ProcessDefinition?processDefinition?=?ProcessDefinition.parseXmlResource("forkjoin/processDefinition.xml"); ??
  • ????????ProcessInstance?processInstance?=?new?ProcessInstance(processDefinition); ??
  • ????????processInstance.getContextInstance().setVariable("param",?10); ??
  • ????????Token?token?=?processInstance.getRootToken(); ??
  • ????????token.signal(); ??
  • ????} ??
  • }??
  • package com.royzhou.test;import org.jbpm.graph.def.ProcessDefinition; import org.jbpm.graph.exe.ProcessInstance; import org.jbpm.graph.exe.Token;public class ForkJoin {public static void main(String[] args) {ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("forkjoin/processDefinition.xml");ProcessInstance processInstance = new ProcessInstance(processDefinition);processInstance.getContextInstance().setVariable("param", 10);Token token = processInstance.getRootToken();token.signal();} }
    執行成功之后后臺輸出:
    node3 enter
    node4 enter

    修改我們的param改為2000再次執行,后臺變為:
    node1 enter
    node2 enter

    6、Decision節點
    Decision節點是判斷節點,當流程到達decision節點之后會有多個路由選擇,我們可以在這個節點上定義handler或者是使用腳本等等來決定流程走向。Decision節點不同于Fork節點,它只能選擇多個Transition中的其中一個,而Fork節點是并行的。
    舉例說明一下:
    流程定義由一個start節點,一個end節點,一個Decision節點以及分支中的3個node節點組成,在Decision我們設置了delegation,使用實現DecisionHandler接口的類SelectNode來判斷流程走向,它返回的結果是其中分支的名稱,流程定義的xml文件如下:
    Xml代碼 ?
  • ????<?xml?version="1.0"?encoding="UTF-8"?>??
  • <process-definition??xmlns="urn:jbpm.org:jpdl-3.2"??name="decision">??
  • ????<start-state?name="start-state1">??
  • ????????<transition?to="decision1"></transition>??
  • ????</start-state>??
  • ????<decision?name="decision1">??
  • ????????<handler?class="com.royzhou.action.SelectNode"></handler>??
  • ????????<transition?to="node1"?name="to?node1"></transition>??
  • ????????<transition?to="node2"?name="to?node2"></transition>??
  • ????????<transition?to="node3"?name="to?node3"></transition>??
  • ????</decision>??
  • ????<node?name="node1">??
  • ????????<script>??
  • ????????????print(&quot;node1?enter&quot;) ??
  • ????????</script>??
  • ????</node>??
  • ????<node?name="node2">??
  • ????????<script>??
  • ????????????print(&quot;node2?enter&quot;) ??
  • ????????</script>??
  • ????????<transition?to="end-state1"></transition>??
  • ????</node>??
  • ????<node?name="node3">??
  • ????????<script>??
  • ????????????print(&quot;node3?enter&quot;) ??
  • ????????</script>??
  • ????</node>??
  • ????<end-state?name="end-state1"></end-state>??
  • </process-definition>??
  • <?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="decision"><start-state name="start-state1"><transition to="decision1"></transition></start-state><decision name="decision1"><handler class="com.royzhou.action.SelectNode"></handler><transition to="node1" name="to node1"></transition><transition to="node2" name="to node2"></transition><transition to="node3" name="to node3"></transition></decision><node name="node1"><script>print(&quot;node1 enter&quot;)</script></node><node name="node2"><script>print(&quot;node2 enter&quot;)</script><transition to="end-state1"></transition></node><node name="node3"><script>print(&quot;node3 enter&quot;)</script></node><end-state name="end-state1"></end-state> </process-definition>
    SelectNode類:(必須實現DecisionHandler接口并重寫decide方法,返回值是要走的transition的名稱)
    Java代碼 ?
  • package?com.royzhou.action; ??
  • ??
  • import?org.jbpm.graph.exe.ExecutionContext; ??
  • import?org.jbpm.graph.node.DecisionHandler; ??
  • //實現DecisionHandler接口 ??
  • public?class?SelectNode?implements?DecisionHandler?{ ??
  • ????public?String?decide(ExecutionContext?executionContext)?throws?Exception?{ ??
  • ????????//通過流程變量來判斷要走哪個transition ??
  • ????????String?whichWay?=?executionContext.getVariable("whichWay").toString(); ??
  • ????????return?whichWay; ??
  • ????} ??
  • }??
  • package com.royzhou.action;import org.jbpm.graph.exe.ExecutionContext; import org.jbpm.graph.node.DecisionHandler; //實現DecisionHandler接口 public class SelectNode implements DecisionHandler {public String decide(ExecutionContext executionContext) throws Exception {//通過流程變量來判斷要走哪個transitionString whichWay = executionContext.getVariable("whichWay").toString();return whichWay;} }
    測試類:
    Java代碼 ?
  • package?com.royzhou.test; ??
  • ??
  • import?org.jbpm.graph.def.ProcessDefinition; ??
  • import?org.jbpm.graph.exe.ProcessInstance; ??
  • import?org.jbpm.graph.exe.Token; ??
  • ??
  • public?class?Decision?{ ??
  • ???? ??
  • ????public?static?void?main(String[]?args)?{ ??
  • ????????ProcessDefinition?processDefinition?=?ProcessDefinition.parseXmlResource("decision/processDefinition.xml"); ??
  • ????????ProcessInstance?processInstance?=?new?ProcessInstance(processDefinition); ??
  • ????????processInstance.getContextInstance().setVariable("whichWay",?"to?node2"); ??
  • ????????Token?token?=?processInstance.getRootToken(); ??
  • ????????token.signal(); ??
  • ????} ??
  • }??
  • package com.royzhou.test;import org.jbpm.graph.def.ProcessDefinition; import org.jbpm.graph.exe.ProcessInstance; import org.jbpm.graph.exe.Token;public class Decision {public static void main(String[] args) {ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("decision/processDefinition.xml");ProcessInstance processInstance = new ProcessInstance(processDefinition);processInstance.getContextInstance().setVariable("whichWay", "to node2");Token token = processInstance.getRootToken();token.signal();} }
    運行測試類,后臺打印出? :
    node2 enter
    修改流程變量whichWay為to node1 重新運行,后臺打印出:
    node1 enter
    說明我們的decision節點正確處理了其走向。

    除了使用delegation,我們也可以在流程文件中直接定義decision節點的expression屬性,如下所示:
    Xml代碼 ?
  • <decision?name="decision1"?expression="#{whichWay}">??
  • ????<!--? ?
  • ????<handler?class="com.royzhou.action.SelectNode"></handler>?
  • ?????-->??
  • ????<transition?to="node1"?name="to?node1"></transition>??
  • ????<transition?to="node2"?name="to?node2"></transition>??
  • ????<transition?to="node3"?name="to?node3"></transition>??
  • </decision>??
  • <decision name="decision1" expression="#{whichWay}"><!-- <handler class="com.royzhou.action.SelectNode"></handler>--><transition to="node1" name="to node1"></transition><transition to="node2" name="to node2"></transition><transition to="node3" name="to node3"></transition></decision>
    這里采用的是JPDL表達式來指定流程走向,JPDL表達式是一種類似EL表達式的語言。
    上面expression表示從流程變量中獲取whichWay這個變量作為我們流程走向的選擇。

    重新運行我們的測試類。發現結果與上面一種做法相同。

    此外我們還可以直接在transition節點下定義condition標簽,配合JPDL表達式來作為我們的判斷依據
    Xml代碼 ?
  • <decision?name="decision1">??
  • ????????<transition?to="node1"?name="to?node1">??
  • ????????????<condition?expression="#{whichWay?==?'to?node1'}"></condition>??
  • ????????</transition>??
  • ????????<transition?to="node2"?name="to?node2">??
  • ????????????<condition?expression="#{whichWay?==?'to?node2'}"></condition>??
  • ????????</transition>??
  • ????????<transition?to="node3"?name="to?node3">??
  • ????????????<condition?expression="#{whichWay?==?'to?node3'}"></condition>??
  • ????????</transition>??
  • ????</decision>??
  • <decision name="decision1"><transition to="node1" name="to node1"><condition expression="#{whichWay == 'to node1'}"></condition></transition><transition to="node2" name="to node2"><condition expression="#{whichWay == 'to node2'}"></condition></transition><transition to="node3" name="to node3"><condition expression="#{whichWay == 'to node3'}"></condition></transition></decision>
    再次運行測試程序發現結果仍然一致。

    由此可見 Decision節點支持我們使用delegation、condition以及expression三種方式來指定流程走向。

    7、Process State節點
    子流程節點可以簡化我們的復雜流程。主流程與子流程之間可以共享變量。如果使用子流程,在主流程發布之前必須先發布子流程。
    舉例說明一下主流程與子流程及其變量共享:
    主流程定義文件mainprocess/processdefinition.xml
    Xml代碼 ?
  • <?xml?version="1.0"?encoding="UTF-8"?>??
  • <process-definition??xmlns="urn:jbpm.org:jpdl-3.2"??name="mainprocess">??
  • ????<start-state?name="start-state1">??
  • ????????<transition?to="task-node1"></transition>??
  • ????</start-state>??
  • ????<task-node?name="task-node1">??
  • ????????<event?type="node-enter">??
  • ????????????<script>??
  • ????????????????print(&quot;main?task?node1?enter&quot;) ??
  • ????????????</script>??
  • ????????</event>??
  • ????????<task?name="maintask1">??
  • ????????????<assignment?actor-id="maintask1"></assignment>??
  • ????????</task>??
  • ????????<transition?to="process-state1"></transition>??
  • ????</task-node>??
  • ????<process-state?name="process-state1">??
  • ????????<sub-process?name="subprocess"/>??
  • ????????<variable?name="mainParam"?access="read"></variable>??
  • ????????<variable?name="subParam"?access="write"></variable>??
  • ????????<transition?to="task-node2"></transition>??
  • ????</process-state>??
  • ????<task-node?name="task-node2">??
  • ????????<event?type="node-enter">??
  • ????????????<script>??
  • ????????????????print(&quot;main?task?node2?enter&quot;) ??
  • ????????????</script>??
  • ????????</event>??
  • ????????<task?name="maintask2">??
  • ????????????<assignment?actor-id="maintask2"></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="urn:jbpm.org:jpdl-3.2" name="mainprocess"><start-state name="start-state1"><transition to="task-node1"></transition></start-state><task-node name="task-node1"><event type="node-enter"><script>print(&quot;main task node1 enter&quot;)</script></event><task name="maintask1"><assignment actor-id="maintask1"></assignment></task><transition to="process-state1"></transition></task-node><process-state name="process-state1"><sub-process name="subprocess"/><variable name="mainParam" access="read"></variable><variable name="subParam" access="write"></variable><transition to="task-node2"></transition></process-state><task-node name="task-node2"><event type="node-enter"><script>print(&quot;main task node2 enter&quot;)</script></event><task name="maintask2"><assignment actor-id="maintask2"></assignment></task><transition to="end-state1"></transition></task-node><end-state name="end-state1"></end-state> </process-definition>
    主流程中設置了process-state節點,其sub-process 的name屬性表示子流程的名稱,
    <variable name="mainParam" access="read"></variable>表示從主流程讀取mainParam變量
    <variable name="subParam" access="write"></variable>表示子流程將變量subParam寫回主流程中。

    子流程定義文件:subprocess/processdefinition.xml
    Xml代碼 ?
  • <?xml?version="1.0"?encoding="UTF-8"?>??
  • <process-definition??xmlns="urn:jbpm.org:jpdl-3.2"??name="subprocess">??
  • ????<start-state?name="start-state1">??
  • ????????<transition?to="task-node1"></transition>??
  • ????</start-state>??
  • ????<task-node?name="task-node1">??
  • ????????<event?type="node-enter">??
  • ????????????<script>??
  • ????????????????print(&quot;sub?task?node1?enter&quot;) ??
  • ????????????</script>??
  • ????????</event>??
  • ????????<task?name="subtask1">??
  • ????????????<assignment?actor-id="subtask1"></assignment>??
  • ????????</task>??
  • ????????<event?type="node-enter">??
  • ????????????<script>??
  • ????????????????print(&quot;sub?task?node1?enter&quot;) ??
  • ????????????</script>??
  • ????????</event>??
  • ????????<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="urn:jbpm.org:jpdl-3.2" name="subprocess"><start-state name="start-state1"><transition to="task-node1"></transition></start-state><task-node name="task-node1"><event type="node-enter"><script>print(&quot;sub task node1 enter&quot;)</script></event><task name="subtask1"><assignment actor-id="subtask1"></assignment></task><event type="node-enter"><script>print(&quot;sub task node1 enter&quot;)</script></event><transition to="end-state1"></transition></task-node><end-state name="end-state1"></end-state> </process-definition>
    測試類:
    Java代碼 ?
  • package?com.royzhou.test; ??
  • ??
  • import?java.io.FileNotFoundException; ??
  • ??
  • import?org.jbpm.JbpmConfiguration; ??
  • import?org.jbpm.JbpmContext; ??
  • import?org.jbpm.graph.def.ProcessDefinition; ??
  • import?org.jbpm.graph.exe.ProcessInstance; ??
  • import?org.jbpm.graph.exe.Token; ??
  • import?org.jbpm.taskmgmt.exe.TaskInstance; ??
  • ??
  • public?class?SubProcess?{ ??
  • ???? ??
  • ????public?static?void?init()?{ ??
  • ????????JbpmConfiguration?jbpmConfiguration?=?JbpmConfiguration.getInstance(); ??
  • ????????jbpmConfiguration.createSchema(); ??
  • ????} ??
  • ???? ??
  • ????public?static?void?deploySub()?throws?FileNotFoundException?{ ??
  • ????????JbpmConfiguration?jbpmConfiguration?=?JbpmConfiguration.getInstance(); ??
  • ????????JbpmContext?jbpmContext?=?jbpmConfiguration.createJbpmContext(); ??
  • ????????try?{ ??
  • ????????????ProcessDefinition?subProcessDefinition?=?ProcessDefinition.parseXmlResource("subprocess/processDefinition.xml"); ??
  • ????????????jbpmContext.deployProcessDefinition(subProcessDefinition); ??
  • ????????}?catch(Exception?e)?{ ??
  • ????????????e.printStackTrace(); ??
  • ????????}?finally?{ ??
  • ????????????jbpmContext.close(); ??
  • ????????} ??
  • ????} ??
  • ???? ??
  • ????public?static?void?deployMain()?throws?FileNotFoundException?{ ??
  • ????????JbpmConfiguration?jbpmConfiguration?=?JbpmConfiguration.getInstance(); ??
  • ????????JbpmContext?jbpmContext?=?jbpmConfiguration.createJbpmContext(); ??
  • ????????try?{ ??
  • ????????????ProcessDefinition?mainProcessDefinition?=?ProcessDefinition.parseXmlResource("mainprocess/processDefinition.xml"); ??
  • ????????????jbpmContext.deployProcessDefinition(mainProcessDefinition); ??
  • ????????}?catch(Exception?e)?{ ??
  • ????????????e.printStackTrace(); ??
  • ????????}?finally?{ ??
  • ????????????jbpmContext.close(); ??
  • ????????} ??
  • ????} ??
  • ???? ??
  • ????public?static?void?startProcess()?{ ??
  • ????????JbpmConfiguration?jbpmConfiguration?=?JbpmConfiguration.getInstance(); ??
  • ????????JbpmContext?jbpmContext?=?jbpmConfiguration.createJbpmContext(); ??
  • ????????try?{ ??
  • ????????????ProcessDefinition?processDefinition?=?jbpmContext.getGraphSession().findLatestProcessDefinition("mainprocess"); ??
  • ????????????ProcessInstance?processInstance?=?new?ProcessInstance(processDefinition); ??
  • ????????????Token?token?=?processInstance.getRootToken(); ??
  • ????????????token.signal(); ??
  • ????????}?catch?(Exception?e)?{ ??
  • ????????????e.printStackTrace(); ??
  • ????????}?finally?{ ??
  • ????????????jbpmContext.close(); ??
  • ????????} ??
  • ????} ??
  • ???? ??
  • ????public?static?void?startMainTask1()?{ ??
  • ????????JbpmConfiguration?jbpmConfiguration?=?JbpmConfiguration.getInstance(); ??
  • ????????JbpmContext?jbpmContext?=?jbpmConfiguration.createJbpmContext(); ??
  • ????????try?{ ??
  • ????????????//主流程maintask1 ??
  • ????????????TaskInstance?mainTaskInstance1?=?jbpmContext.loadTaskInstance(1L); ??
  • ????????????//設置主流程變量 ??
  • ????????????mainTaskInstance1.getContextInstance().setVariable("mainParam",?"主流程設置的變量"); ??
  • ????????????mainTaskInstance1.end(); ??
  • ????????}?catch?(Exception?e)?{ ??
  • ????????????e.printStackTrace(); ??
  • ????????}?finally?{ ??
  • ????????????jbpmContext.close(); ??
  • ????????} ??
  • ????} ??
  • ???? ??
  • ????public?static?void?startSubTask1()?{ ??
  • ????????JbpmConfiguration?jbpmConfiguration?=?JbpmConfiguration.getInstance(); ??
  • ????????JbpmContext?jbpmContext?=?jbpmConfiguration.createJbpmContext(); ??
  • ????????try?{ ??
  • ????????????//子流程subtask1 ??
  • ????????????TaskInstance?subTaskInstance1?=?jbpmContext.loadTaskInstance(2L); ??
  • ????????????//獲取主流程變量 ??
  • ????????????System.out.println(subTaskInstance1.getName()?+?"子流程讀取主流程變量,mainParam的值是:"?+?subTaskInstance1.getContextInstance().getVariable("mainParam").toString()); ??
  • ????????????//設置子流程變量 ??
  • ????????????subTaskInstance1.getContextInstance().setVariable("subParam",?"子流程設置的變量"); ??
  • ????????????subTaskInstance1.end(); ??
  • ????????}?catch?(Exception?e)?{ ??
  • ????????????e.printStackTrace(); ??
  • ????????}?finally?{ ??
  • ????????????jbpmContext.close(); ??
  • ????????} ??
  • ????} ??
  • ???? ??
  • ????public?static?void?startMainTask2()?{ ??
  • ????????JbpmConfiguration?jbpmConfiguration?=?JbpmConfiguration.getInstance(); ??
  • ????????JbpmContext?jbpmContext?=?jbpmConfiguration.createJbpmContext(); ??
  • ????????try?{ ??
  • ????????????TaskInstance?mainTaskInstance2?=?jbpmContext.loadTaskInstance(3L); ??
  • ????????????//讀取子流程變量 ??
  • ????????????System.out.println(mainTaskInstance2.getName()+"主流程讀取子流程變量,subParam的值是:"?+?mainTaskInstance2.getContextInstance().getVariable("subParam").toString()); ??
  • ????????????mainTaskInstance2.end(); ??
  • ????????}?catch?(Exception?e)?{ ??
  • ????????????e.printStackTrace(); ??
  • ????????}?finally?{ ??
  • ????????????jbpmContext.close(); ??
  • ????????} ??
  • ????}? ??
  • ???? ??
  • ????public?static?void?main(String[]?args)?throws?FileNotFoundException?{ ??
  • ????????//數據庫清理 ??
  • ????????SubProcess.init(); ??
  • ????????//發布流程,必須先發布子流程再發布主流程 ??
  • ????????SubProcess.deploySub(); ??
  • ????????SubProcess.deployMain(); ??
  • ????????SubProcess.startProcess(); ??
  • ????????SubProcess.startMainTask1(); ??
  • ????????SubProcess.startSubTask1(); ??
  • ????????SubProcess.startMainTask2(); ??
  • ????} ??
  • }??
  • package com.royzhou.test;import java.io.FileNotFoundException;import org.jbpm.JbpmConfiguration; import org.jbpm.JbpmContext; import org.jbpm.graph.def.ProcessDefinition; import org.jbpm.graph.exe.ProcessInstance; import org.jbpm.graph.exe.Token; import org.jbpm.taskmgmt.exe.TaskInstance;public class SubProcess {public static void init() {JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();jbpmConfiguration.createSchema();}public static void deploySub() throws FileNotFoundException {JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();try {ProcessDefinition subProcessDefinition = ProcessDefinition.parseXmlResource("subprocess/processDefinition.xml");jbpmContext.deployProcessDefinition(subProcessDefinition);} catch(Exception e) {e.printStackTrace();} finally {jbpmContext.close();}}public static void deployMain() throws FileNotFoundException {JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();try {ProcessDefinition mainProcessDefinition = ProcessDefinition.parseXmlResource("mainprocess/processDefinition.xml");jbpmContext.deployProcessDefinition(mainProcessDefinition);} catch(Exception e) {e.printStackTrace();} finally {jbpmContext.close();}}public static void startProcess() {JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();try {ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition("mainprocess");ProcessInstance processInstance = new ProcessInstance(processDefinition);Token token = processInstance.getRootToken();token.signal();} catch (Exception e) {e.printStackTrace();} finally {jbpmContext.close();}}public static void startMainTask1() {JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();try {//主流程maintask1TaskInstance mainTaskInstance1 = jbpmContext.loadTaskInstance(1L);//設置主流程變量mainTaskInstance1.getContextInstance().setVariable("mainParam", "主流程設置的變量");mainTaskInstance1.end();} catch (Exception e) {e.printStackTrace();} finally {jbpmContext.close();}}public static void startSubTask1() {JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();try {//子流程subtask1TaskInstance subTaskInstance1 = jbpmContext.loadTaskInstance(2L);//獲取主流程變量System.out.println(subTaskInstance1.getName() + "子流程讀取主流程變量,mainParam的值是:" + subTaskInstance1.getContextInstance().getVariable("mainParam").toString());//設置子流程變量subTaskInstance1.getContextInstance().setVariable("subParam", "子流程設置的變量");subTaskInstance1.end();} catch (Exception e) {e.printStackTrace();} finally {jbpmContext.close();}}public static void startMainTask2() {JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();try {TaskInstance mainTaskInstance2 = jbpmContext.loadTaskInstance(3L);//讀取子流程變量System.out.println(mainTaskInstance2.getName()+"主流程讀取子流程變量,subParam的值是:" + mainTaskInstance2.getContextInstance().getVariable("subParam").toString());mainTaskInstance2.end();} catch (Exception e) {e.printStackTrace();} finally {jbpmContext.close();}} public static void main(String[] args) throws FileNotFoundException {//數據庫清理SubProcess.init();//發布流程,必須先發布子流程再發布主流程SubProcess.deploySub();SubProcess.deployMain();SubProcess.startProcess();SubProcess.startMainTask1();SubProcess.startSubTask1();SubProcess.startMainTask2();} }
    運行上面程序,成功執行之后結果為:
    main task node1 enter
    sub task node1 enter
    sub task node1 enter
    subtask1子流程讀取主流程變量,mainParam的值是:主流程設置的變量
    main task node2 enter
    maintask2主流程讀取子流程變量,subParam的值是:子流程設置的變量

    8、Mail Node 節點
    該節點可以實現郵件的發送,具有通知提醒功能。
    具體有兩種配置方式:
    通過mail node節點的template屬性設置,采用此種方式需要修改jbpm.mail.template.xml文件里的模版,加上我們需要的模版,具體模版設置可參照里面已有模版。舉例說明下:
    流程模版文件:start -> mail node ->end
    Xml代碼 ?
  • <?xml?version="1.0"?encoding="UTF-8"?>??
  • <process-definition??xmlns="urn:jbpm.org:jpdl-3.2"??name="mail">??
  • ????<start-state?name="start-state1">??
  • ????????<transition?to="mail-node1"></transition>??
  • ????</start-state>??
  • ????<mail-node?name="mail-node1"?template="test">??
  • ????????<event?type="node-enter">??
  • ????????????<script>??
  • ????????????????print(&quot;enter?mail?node&quot;) ??
  • ????????????</script>??
  • ????????</event>??
  • ????????<event?type="node-leave">??
  • ????????????<script>??
  • ????????????????print(&quot;leave?mail?node&quot;) ??
  • ????????????</script>??
  • ????????</event>??
  • ????????<transition?to="end-state1"></transition>??
  • ????</mail-node>??
  • ????<end-state?name="end-state1"></end-state>??
  • </process-definition>??
  • <?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="mail"><start-state name="start-state1"><transition to="mail-node1"></transition></start-state><mail-node name="mail-node1" template="test"><event type="node-enter"><script>print(&quot;enter mail node&quot;)</script></event><event type="node-leave"><script>print(&quot;leave mail node&quot;)</script></event><transition to="end-state1"></transition></mail-node><end-state name="end-state1"></end-state> </process-definition>
    我們使用的模版是test,但是jbpm.mail.template.xml沒有,所以需要我們自己加:
    Xml代碼 ?
  • <mail-template?name="test">??
  • ????????<actors>#{actorId}</actors>??
  • ????????<subject>mail?node?節點測試</subject>??
  • ????????<text><![CDATA[Hi?#{actorId},?
  • ????????這是mail?node節點的測試內容。 ?
  • ????????]]></text>??
  • ????</mail-template>????
  • <mail-template name="test"><actors>#{actorId}</actors><subject>mail node 節點測試</subject><text><![CDATA[Hi #{actorId},這是mail node節點的測試內容。]]></text></mail-template>
    這個是我們自己定義的模版,其中actors標簽表示的是收件人的地址,需要使用郵件解析類解析,郵件解析類是一個實現AddressResolver接口的類。并且需要在jbpm.cfg.xml中配置,告訴jbpm要使用這個類去解析獲取發送郵件的地址。
    Java代碼 ?
  • package?com.royzhou.util; ??
  • ??
  • import?org.jbpm.mail.AddressResolver; ??
  • ??
  • public?class?MailAddressResolver?implements?AddressResolver?{ ??
  • ??
  • ????public?Object?resolveAddress(String?actorId)?{ ??
  • ????????return?"royzhou1985@foxmail.com"; ??
  • ????} ??
  • }??
  • package com.royzhou.util;import org.jbpm.mail.AddressResolver;public class MailAddressResolver implements AddressResolver {public Object resolveAddress(String actorId) {return "royzhou1985@foxmail.com";} }
    下面是jbpm.cfg.xml的配置內容。
    Xml代碼 ?
  • <jbpm-configuration>??
  • ????<!--?郵件解析類?-->??
  • ????<bean?name="jbpm.mail.address.resolver"??
  • ????????class="com.royzhou.util.MailAddressResolver"?singleton="true"?/>??
  • ????<!--?郵箱配置信息?-->??
  • ????<string?name="resource.mail.properties"?value="jbpm.mail.properties"?/>??
  • ????<!--?處理郵件發送的類?-->??
  • ????<string?name="mail.class.name"?value="com.royzhou.util.Mail"?/>??
  • ????<!--?發送人地址?-->??
  • ????<string?name="jbpm.mail.from.address"?value="test@163.com"></string>??
  • </jbpm-configuration>??
  • <jbpm-configuration><!-- 郵件解析類 --><bean name="jbpm.mail.address.resolver"class="com.royzhou.util.MailAddressResolver" singleton="true" /><!-- 郵箱配置信息 --><string name="resource.mail.properties" value="jbpm.mail.properties" /><!-- 處理郵件發送的類 --><string name="mail.class.name" value="com.royzhou.util.Mail" /><!-- 發送人地址 --><string name="jbpm.mail.from.address" value="test@163.com"></string> </jbpm-configuration>

    郵箱配置信息如下:
    mail.smtp.host=smtp.163.com
    mail.smtp.user=test
    mail.smtp.password=test
    mail.smtp.auth=true

    配置中我們使用的是自己的郵件發送類,這是因為jbpm自己提供的郵件發送類沒有提供身份認證,直接使用會報異常。
    修改之后的郵件發送類如下:
    Java代碼 ?
  • package?com.royzhou.util; ??
  • ??
  • import?java.io.InputStream; ??
  • import?java.io.Serializable; ??
  • import?java.util.ArrayList; ??
  • import?java.util.Arrays; ??
  • import?java.util.Collection; ??
  • import?java.util.Date; ??
  • import?java.util.HashMap; ??
  • import?java.util.Iterator; ??
  • import?java.util.List; ??
  • import?java.util.Map; ??
  • import?java.util.Properties; ??
  • import?java.util.StringTokenizer; ??
  • ??
  • import?javax.mail.Message; ??
  • import?javax.mail.PasswordAuthentication; ??
  • import?javax.mail.Session; ??
  • import?javax.mail.Transport; ??
  • import?javax.mail.internet.InternetAddress; ??
  • import?javax.mail.internet.MimeMessage; ??
  • import?javax.mail.Authenticator; ??
  • ??
  • import?org.apache.commons.logging.Log; ??
  • import?org.apache.commons.logging.LogFactory; ??
  • import?org.jbpm.JbpmConfiguration; ??
  • import?org.jbpm.JbpmException; ??
  • import?org.jbpm.graph.def.ActionHandler; ??
  • import?org.jbpm.graph.exe.ExecutionContext; ??
  • import?org.jbpm.jpdl.el.ELException; ??
  • import?org.jbpm.jpdl.el.VariableResolver; ??
  • import?org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator; ??
  • import?org.jbpm.mail.AddressResolver; ??
  • import?org.jbpm.util.ClassLoaderUtil; ??
  • import?org.jbpm.util.XmlUtil; ??
  • ??
  • public?class?Mail?implements?ActionHandler?{ ??
  • ??
  • ??private?static?final?long?serialVersionUID?=?1L; ??
  • ?? ??
  • ??String?template?=?null; ??
  • ??String?actors?=?null; ??
  • ??String?to?=?null; ??
  • ??String?bcc?=?null; ??
  • ??String?bccActors?=?null; ??
  • ??String?subject?=?null; ??
  • ??String?text?=?null; ??
  • ?? ??
  • ??ExecutionContext?executionContext?=?null; ??
  • ?? ??
  • ??public?Mail()?{ ??
  • ??} ??
  • ??
  • ??public?Mail(String?template, ??
  • ??????????????String?actors, ??
  • ??????????????String?to, ??
  • ??????????????String?subject, ??
  • ??????????????String?text)?{ ??
  • ????this.template?=?template; ??
  • ????this.actors?=?actors; ??
  • ????this.to?=?to; ??
  • ????this.subject?=?subject; ??
  • ????this.text?=?text; ??
  • ??} ??
  • ?? ??
  • ??public?Mail(String?template, ??
  • ??????String?actors, ??
  • ??????String?to, ??
  • ??????String?bccActors, ??
  • ??????String?bcc, ??
  • ??????String?subject, ??
  • ??????String?text)?{ ??
  • ????this.template?=?template; ??
  • ????this.actors?=?actors; ??
  • ????this.to?=?to; ??
  • ????this.bccActors?=?bccActors; ??
  • ????this.bcc?=?bcc; ??
  • ????this.subject?=?subject; ??
  • ????this.text?=?text; ??
  • ??}?? ??
  • ?? ??
  • ??public?void?execute(ExecutionContext?executionContext)?{ ??
  • ????this.executionContext?=?executionContext; ??
  • ????send(); ??
  • ??} ??
  • ??
  • ??public?List?getRecipients()?{ ??
  • ????List?recipients?=?new?ArrayList(); ??
  • ????if?(actors!=null)?{ ??
  • ??????String?evaluatedActors?=?evaluate(actors); ??
  • ??????List?tokenizedActors?=?tokenize(evaluatedActors); ??
  • ??????if?(tokenizedActors!=null)?{ ??
  • ????????recipients.addAll(resolveAddresses(tokenizedActors)); ??
  • ??????} ??
  • ????} ??
  • ????if?(to!=null)?{ ??
  • ??????String?resolvedTo?=?evaluate(to); ??
  • ??????recipients.addAll(tokenize(resolvedTo)); ??
  • ????} ??
  • ????return?recipients; ??
  • ??} ??
  • ??
  • ??public?List?getBccRecipients()?{ ??
  • ????List?recipients?=?new?ArrayList(); ??
  • ????if?(bccActors!=null)?{ ??
  • ??????String?evaluatedActors?=?evaluate(bccActors); ??
  • ??????List?tokenizedActors?=?tokenize(evaluatedActors); ??
  • ??????if?(tokenizedActors!=null)?{ ??
  • ????????recipients.addAll(resolveAddresses(tokenizedActors)); ??
  • ??????} ??
  • ????} ??
  • ????if?(bcc!=null)?{ ??
  • ??????String?resolvedTo?=?evaluate(to); ??
  • ??????recipients.addAll(tokenize(resolvedTo)); ??
  • ????} ??
  • ????if?(JbpmConfiguration.Configs.hasObject("jbpm.mail.bcc.address"))?{ ??
  • ??????recipients.addAll(tokenize( ??
  • ??????????JbpmConfiguration.Configs.getString("jbpm.mail.bcc.address"))); ??
  • ????} ??
  • ????return?recipients; ??
  • ??} ??
  • ?? ??
  • ??public?String?getSubject()?{ ??
  • ????if?(subject==null)?return?null; ??
  • ????return?evaluate(subject); ??
  • ??} ??
  • ??
  • ??public?String?getText()?{ ??
  • ????if?(text==null)?return?null; ??
  • ????return?evaluate(text); ??
  • ??} ??
  • ??
  • ??public?String?getFromAddress()?{ ??
  • ????if?(JbpmConfiguration.Configs.hasObject("jbpm.mail.from.address"))?{ ??
  • ??????return?JbpmConfiguration.Configs.getString("jbpm.mail.from.address"); ??
  • ????}? ??
  • ????return?"jbpm@noreply"; ??
  • ??} ??
  • ??
  • ??public?void?send()?{ ??
  • ????if?(template!=null)?{ ??
  • ??????Properties?properties?=?getMailTemplateProperties(template); ??
  • ??????if?(actors==null)?{ ??
  • ????????actors?=?properties.getProperty("actors"); ??
  • ??????} ??
  • ??????if?(to==null)?{ ??
  • ????????to?=?properties.getProperty("to"); ??
  • ??????} ??
  • ??????if?(subject==null)?{ ??
  • ????????subject?=?properties.getProperty("subject"); ??
  • ??????} ??
  • ??????if?(text==null)?{ ??
  • ????????text?=?properties.getProperty("text"); ??
  • ??????} ??
  • ??????if?(bcc==null)?{ ??
  • ????????bcc?=?properties.getProperty("bcc"); ??
  • ??????} ??
  • ??????if?(bccActors==null)?{ ??
  • ????????bccActors?=?properties.getProperty("bccActors"); ??
  • ??????} ??
  • ????} ??
  • ???? ??
  • ????send(getMailServerProperties(),? ??
  • ????????????getFromAddress(),? ??
  • ????????????getRecipients(),? ??
  • ????????????getBccRecipients(), ??
  • ????????????getSubject(),? ??
  • ????????????getText()); ??
  • ??} ??
  • ?? ??
  • ??public?static?void?send(Properties?mailServerProperties,?String?fromAddress,?List?recipients,?String?subject,?String?text)?{ ??
  • ????send(mailServerProperties,?fromAddress,?recipients,?null,?subject,?text); ??
  • ??} ??
  • ?? ??
  • ??public?static?void?send(Properties?mailServerProperties,?String?fromAddress,?List?recipients,?List?bccRecipients,?String?subject,?String?text)?{ ??
  • ????if?(?(recipients==null) ??
  • ?????????||?(recipients.isEmpty()) ??
  • ???????)?{ ??
  • ??????log.debug("skipping?mail?because?there?are?no?recipients"); ??
  • ??????return; ??
  • ????} ??
  • ????mailServerProperties.put("mail.smtp.auth",?"true"); ??
  • ????log.debug("sending?email?to?'"+recipients+"'?about?'"+subject+"'"); ??
  • ???? ??
  • ????/** ?
  • ?????*?添加認證類 ?
  • ?????*?royzhou?2009.07.21 ?
  • ?????*/??
  • ????String?userName?=?mailServerProperties.getProperty("mail.smtp.user").toString(); ??
  • ????String?password?=?mailServerProperties.getProperty("mail.smtp.password").toString(); ??
  • ????MyAuthentication?myAuthentication?=?new?MyAuthentication(userName,password); ??
  • ????Session?session?=?Session.getDefaultInstance(mailServerProperties,?myAuthentication); ??
  • ????MimeMessage?message?=?new?MimeMessage(session); ??
  • ????try?{ ??
  • ??????if?(fromAddress!=null)?{ ??
  • ????????message.setFrom(new?InternetAddress(fromAddress)); ??
  • ??????} ??
  • ??????Iterator?iter?=?recipients.iterator(); ??
  • ??????while?(iter.hasNext())?{ ??
  • ????????InternetAddress?recipient?=?new?InternetAddress((String)?iter.next()); ??
  • ????????message.addRecipient(Message.RecipientType.TO,?recipient); ??
  • ??????} ??
  • ??????if?(bccRecipients!=null)?{ ??
  • ????????iter?=?bccRecipients.iterator(); ??
  • ????????while?(iter.hasNext())?{ ??
  • ??????????InternetAddress?recipient?=?new?InternetAddress((String)?iter.next()); ??
  • ??????????message.addRecipient(Message.RecipientType.BCC,?recipient); ??
  • ????????}???????? ??
  • ??????} ??
  • ??????if?(subject!=null)?{ ??
  • ????????message.setSubject(subject); ??
  • ??????} ??
  • ??????if?(text!=null)?{ ??
  • ????????message.setText(text); ??
  • ??????} ??
  • ??????message.setSentDate(new?Date()); ??
  • ?????? ??
  • ??????Transport.send(message); ??
  • ????}?catch?(Exception?e)?{ ??
  • ??????throw?new?JbpmException("couldn't?send?email",?e); ??
  • ????} ??
  • ??} ??
  • ??
  • ??protected?List?tokenize(String?text)?{ ??
  • ????if?(text==null)?{ ??
  • ??????return?null; ??
  • ????} ??
  • ????List?list?=?new?ArrayList(); ??
  • ????StringTokenizer?tokenizer?=?new?StringTokenizer(text,?";:"); ??
  • ????while?(tokenizer.hasMoreTokens())?{ ??
  • ??????list.add(tokenizer.nextToken()); ??
  • ????} ??
  • ????return?list; ??
  • ??} ??
  • ??
  • ??protected?Collection?resolveAddresses(List?actorIds)?{ ??
  • ????List?emailAddresses?=?new?ArrayList(); ??
  • ????Iterator?iter?=?actorIds.iterator(); ??
  • ????while?(iter.hasNext())?{ ??
  • ??????String?actorId?=?(String)?iter.next(); ??
  • ??????AddressResolver?addressResolver?=?(AddressResolver)?JbpmConfiguration.Configs.getObject("jbpm.mail.address.resolver"); ??
  • ??????Object?resolvedAddresses?=?addressResolver.resolveAddress(actorId); ??
  • ??????if?(resolvedAddresses!=null)?{ ??
  • ????????if?(resolvedAddresses?instanceof?String)?{ ??
  • ??????????emailAddresses.add((String)resolvedAddresses); ??
  • ????????}?else?if?(resolvedAddresses?instanceof?Collection)?{ ??
  • ??????????emailAddresses.addAll((Collection)resolvedAddresses); ??
  • ????????}?else?if?(resolvedAddresses?instanceof?String[])?{ ??
  • ??????????emailAddresses.addAll(Arrays.asList((String[])resolvedAddresses)); ??
  • ????????}?else?{ ??
  • ??????????throw?new?JbpmException("Address?resolver?'"+addressResolver+"'?returned?'"+resolvedAddresses.getClass().getName()+"'?instead?of?a?String,?Collection?or?String-array:?"+resolvedAddresses); ??
  • ????????} ??
  • ??????} ??
  • ????} ??
  • ????return?emailAddresses; ??
  • ??} ??
  • ??
  • ??Properties?getMailServerProperties()?{ ??
  • ????Properties?mailServerProperties?=?new?Properties(); ??
  • ??
  • ????if?(JbpmConfiguration.Configs.hasObject("resource.mail.properties"))?{ ??
  • ??????String?mailServerPropertiesResource?=?JbpmConfiguration.Configs.getString("resource.mail.properties"); ??
  • ??????try?{ ??
  • ????????InputStream?mailServerStream?=?ClassLoaderUtil.getStream(mailServerPropertiesResource); ??
  • ????????mailServerProperties.load(mailServerStream); ??
  • ??????}?catch?(Exception?e)?{ ??
  • ????????throw?new?JbpmException("couldn't?get?configuration?properties?for?jbpm?mail?server?from?resource?'"+mailServerPropertiesResource+"'",?e); ??
  • ??????} ??
  • ???? ??
  • ????}?else?if?(JbpmConfiguration.Configs.hasObject("jbpm.mail.smtp.host"))?{ ??
  • ??????String?smtpServer?=?JbpmConfiguration.Configs.getString("jbpm.mail.smtp.host"); ??
  • ??????mailServerProperties.put("mail.smtp.host",?smtpServer); ??
  • ?????? ??
  • ????}?else?{ ??
  • ?????? ??
  • ??????log.error("couldn't?get?mail?properties"); ??
  • ????} ??
  • ??
  • ????return?mailServerProperties; ??
  • ??} ??
  • ??
  • ??static?Map?templates?=?null; ??
  • ??static?Map?templateVariables?=?null; ??
  • ??synchronized?Properties?getMailTemplateProperties(String?templateName)?{ ??
  • ????if?(templates==null)?{ ??
  • ??????templates?=?new?HashMap(); ??
  • ??????String?mailTemplatesResource?=?JbpmConfiguration.Configs.getString("resource.mail.templates"); ??
  • ??????org.w3c.dom.Element?mailTemplatesElement?=?XmlUtil.parseXmlResource(mailTemplatesResource).getDocumentElement(); ??
  • ??????List?mailTemplateElements?=?XmlUtil.elements(mailTemplatesElement,?"mail-template"); ??
  • ??????Iterator?iter?=?mailTemplateElements.iterator(); ??
  • ??????while?(iter.hasNext())?{ ??
  • ????????org.w3c.dom.Element?mailTemplateElement?=?(org.w3c.dom.Element)?iter.next(); ??
  • ??
  • ????????Properties?templateProperties?=?new?Properties(); ??
  • ????????addTemplateProperty(mailTemplateElement,?"actors",?templateProperties); ??
  • ????????addTemplateProperty(mailTemplateElement,?"to",?templateProperties); ??
  • ????????addTemplateProperty(mailTemplateElement,?"subject",?templateProperties); ??
  • ????????addTemplateProperty(mailTemplateElement,?"text",?templateProperties); ??
  • ????????addTemplateProperty(mailTemplateElement,?"bcc",?templateProperties); ??
  • ????????addTemplateProperty(mailTemplateElement,?"bccActors",?templateProperties); ??
  • ??
  • ????????templates.put(mailTemplateElement.getAttribute("name"),?templateProperties); ??
  • ??????} ??
  • ??
  • ??????templateVariables?=?new?HashMap(); ??
  • ??????List?variableElements?=?XmlUtil.elements(mailTemplatesElement,?"variable"); ??
  • ??????iter?=?variableElements.iterator(); ??
  • ??????while?(iter.hasNext())?{ ??
  • ????????org.w3c.dom.Element?variableElement?=?(org.w3c.dom.Element)?iter.next(); ??
  • ????????templateVariables.put(variableElement.getAttribute("name"),?variableElement.getAttribute("value")); ??
  • ??????} ??
  • ????} ??
  • ????return?(Properties)?templates.get(templateName); ??
  • ??} ??
  • ??
  • ??void?addTemplateProperty(org.w3c.dom.Element?mailTemplateElement,?String?property,?Properties?templateProperties)?{ ??
  • ????org.w3c.dom.Element?element?=?XmlUtil.element(mailTemplateElement,?property); ??
  • ????if?(element!=null)?{ ??
  • ??????templateProperties.put(property,?XmlUtil.getContentText(element)); ??
  • ????} ??
  • ??} ??
  • ?? ??
  • ??String?evaluate(String?expression)?{ ??
  • ????if?(expression==null)?{ ??
  • ??????return?null; ??
  • ????} ??
  • ????VariableResolver?variableResolver?=?JbpmExpressionEvaluator.getUsedVariableResolver(); ??
  • ????if?(variableResolver!=null)?{ ??
  • ??????variableResolver?=?new?MailVariableResolver(templateVariables,?variableResolver); ??
  • ????} ??
  • ????return?(String)?JbpmExpressionEvaluator.evaluate(expression,?executionContext,?variableResolver,?null); ??
  • ??} ??
  • ??
  • ??class?MailVariableResolver?implements?VariableResolver,?Serializable?{ ??
  • ????private?static?final?long?serialVersionUID?=?1L; ??
  • ????Map?templateVariables?=?null; ??
  • ????VariableResolver?variableResolver?=?null; ??
  • ??
  • ????public?MailVariableResolver(Map?templateVariables,?VariableResolver?variableResolver)?{ ??
  • ??????this.templateVariables?=?templateVariables; ??
  • ??????this.variableResolver?=?variableResolver; ??
  • ????} ??
  • ??
  • ????public?Object?resolveVariable(String?pName)?throws?ELException?{ ??
  • ??????if?(?(templateVariables!=null) ??
  • ???????????&&?(templateVariables.containsKey(pName)) ??
  • ?????????){ ??
  • ????????return?templateVariables.get(pName); ??
  • ??????} ??
  • ??????return?variableResolver.resolveVariable(pName); ??
  • ????} ??
  • ??} ??
  • ??
  • ??private?static?Log?log?=?LogFactory.getLog(Mail.class); ??
  • } ??
  • ??
  • /** ?
  • ?*?郵箱認證類 ?
  • ?*?@author?royzhou ?
  • ?*?2009.07.21 ?
  • ?*/??
  • class?MyAuthentication?extends?Authenticator?{ ??
  • ????private?String?userName; ??
  • ????private?String?password; ??
  • ????public?MyAuthentication(String?userName,?String?password)?{ ??
  • ????????this.userName?=?userName; ??
  • ????????this.password?=?password; ??
  • ????} ??
  • ????protected?PasswordAuthentication?getPasswordAuthentication()?{ ??
  • ????????return?new?PasswordAuthentication(userName,password); ??
  • ????} ??
  • }??
  • package com.royzhou.util;import java.io.InputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.StringTokenizer;import javax.mail.Message; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.mail.Authenticator;import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jbpm.JbpmConfiguration; import org.jbpm.JbpmException; import org.jbpm.graph.def.ActionHandler; import org.jbpm.graph.exe.ExecutionContext; import org.jbpm.jpdl.el.ELException; import org.jbpm.jpdl.el.VariableResolver; import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator; import org.jbpm.mail.AddressResolver; import org.jbpm.util.ClassLoaderUtil; import org.jbpm.util.XmlUtil;public class Mail implements ActionHandler {private static final long serialVersionUID = 1L;String template = null;String actors = null;String to = null;String bcc = null;String bccActors = null;String subject = null;String text = null;ExecutionContext executionContext = null;public Mail() {}public Mail(String template,String actors,String to,String subject,String text) {this.template = template;this.actors = actors;this.to = to;this.subject = subject;this.text = text;}public Mail(String template,String actors,String to,String bccActors,String bcc,String subject,String text) {this.template = template;this.actors = actors;this.to = to;this.bccActors = bccActors;this.bcc = bcc;this.subject = subject;this.text = text;} public void execute(ExecutionContext executionContext) {this.executionContext = executionContext;send();}public List getRecipients() {List recipients = new ArrayList();if (actors!=null) {String evaluatedActors = evaluate(actors);List tokenizedActors = tokenize(evaluatedActors);if (tokenizedActors!=null) {recipients.addAll(resolveAddresses(tokenizedActors));}}if (to!=null) {String resolvedTo = evaluate(to);recipients.addAll(tokenize(resolvedTo));}return recipients;}public List getBccRecipients() {List recipients = new ArrayList();if (bccActors!=null) {String evaluatedActors = evaluate(bccActors);List tokenizedActors = tokenize(evaluatedActors);if (tokenizedActors!=null) {recipients.addAll(resolveAddresses(tokenizedActors));}}if (bcc!=null) {String resolvedTo = evaluate(to);recipients.addAll(tokenize(resolvedTo));}if (JbpmConfiguration.Configs.hasObject("jbpm.mail.bcc.address")) {recipients.addAll(tokenize(JbpmConfiguration.Configs.getString("jbpm.mail.bcc.address")));}return recipients;}public String getSubject() {if (subject==null) return null;return evaluate(subject);}public String getText() {if (text==null) return null;return evaluate(text);}public String getFromAddress() {if (JbpmConfiguration.Configs.hasObject("jbpm.mail.from.address")) {return JbpmConfiguration.Configs.getString("jbpm.mail.from.address");} return "jbpm@noreply";}public void send() {if (template!=null) {Properties properties = getMailTemplateProperties(template);if (actors==null) {actors = properties.getProperty("actors");}if (to==null) {to = properties.getProperty("to");}if (subject==null) {subject = properties.getProperty("subject");}if (text==null) {text = properties.getProperty("text");}if (bcc==null) {bcc = properties.getProperty("bcc");}if (bccActors==null) {bccActors = properties.getProperty("bccActors");}}send(getMailServerProperties(), getFromAddress(), getRecipients(), getBccRecipients(),getSubject(), getText());}public static void send(Properties mailServerProperties, String fromAddress, List recipients, String subject, String text) {send(mailServerProperties, fromAddress, recipients, null, subject, text);}public static void send(Properties mailServerProperties, String fromAddress, List recipients, List bccRecipients, String subject, String text) {if ( (recipients==null)|| (recipients.isEmpty())) {log.debug("skipping mail because there are no recipients");return;}mailServerProperties.put("mail.smtp.auth", "true");log.debug("sending email to '"+recipients+"' about '"+subject+"'");/*** 添加認證類* royzhou 2009.07.21*/String userName = mailServerProperties.getProperty("mail.smtp.user").toString();String password = mailServerProperties.getProperty("mail.smtp.password").toString();MyAuthentication myAuthentication = new MyAuthentication(userName,password);Session session = Session.getDefaultInstance(mailServerProperties, myAuthentication);MimeMessage message = new MimeMessage(session);try {if (fromAddress!=null) {message.setFrom(new InternetAddress(fromAddress));}Iterator iter = recipients.iterator();while (iter.hasNext()) {InternetAddress recipient = new InternetAddress((String) iter.next());message.addRecipient(Message.RecipientType.TO, recipient);}if (bccRecipients!=null) {iter = bccRecipients.iterator();while (iter.hasNext()) {InternetAddress recipient = new InternetAddress((String) iter.next());message.addRecipient(Message.RecipientType.BCC, recipient);} }if (subject!=null) {message.setSubject(subject);}if (text!=null) {message.setText(text);}message.setSentDate(new Date());Transport.send(message);} catch (Exception e) {throw new JbpmException("couldn't send email", e);}}protected List tokenize(String text) {if (text==null) {return null;}List list = new ArrayList();StringTokenizer tokenizer = new StringTokenizer(text, ";:");while (tokenizer.hasMoreTokens()) {list.add(tokenizer.nextToken());}return list;}protected Collection resolveAddresses(List actorIds) {List emailAddresses = new ArrayList();Iterator iter = actorIds.iterator();while (iter.hasNext()) {String actorId = (String) iter.next();AddressResolver addressResolver = (AddressResolver) JbpmConfiguration.Configs.getObject("jbpm.mail.address.resolver");Object resolvedAddresses = addressResolver.resolveAddress(actorId);if (resolvedAddresses!=null) {if (resolvedAddresses instanceof String) {emailAddresses.add((String)resolvedAddresses);} else if (resolvedAddresses instanceof Collection) {emailAddresses.addAll((Collection)resolvedAddresses);} else if (resolvedAddresses instanceof String[]) {emailAddresses.addAll(Arrays.asList((String[])resolvedAddresses));} else {throw new JbpmException("Address resolver '"+addressResolver+"' returned '"+resolvedAddresses.getClass().getName()+"' instead of a String, Collection or String-array: "+resolvedAddresses);}}}return emailAddresses;}Properties getMailServerProperties() {Properties mailServerProperties = new Properties();if (JbpmConfiguration.Configs.hasObject("resource.mail.properties")) {String mailServerPropertiesResource = JbpmConfiguration.Configs.getString("resource.mail.properties");try {InputStream mailServerStream = ClassLoaderUtil.getStream(mailServerPropertiesResource);mailServerProperties.load(mailServerStream);} catch (Exception e) {throw new JbpmException("couldn't get configuration properties for jbpm mail server from resource '"+mailServerPropertiesResource+"'", e);}} else if (JbpmConfiguration.Configs.hasObject("jbpm.mail.smtp.host")) {String smtpServer = JbpmConfiguration.Configs.getString("jbpm.mail.smtp.host");mailServerProperties.put("mail.smtp.host", smtpServer);} else {log.error("couldn't get mail properties");}return mailServerProperties;}static Map templates = null;static Map templateVariables = null;synchronized Properties getMailTemplateProperties(String templateName) {if (templates==null) {templates = new HashMap();String mailTemplatesResource = JbpmConfiguration.Configs.getString("resource.mail.templates");org.w3c.dom.Element mailTemplatesElement = XmlUtil.parseXmlResource(mailTemplatesResource).getDocumentElement();List mailTemplateElements = XmlUtil.elements(mailTemplatesElement, "mail-template");Iterator iter = mailTemplateElements.iterator();while (iter.hasNext()) {org.w3c.dom.Element mailTemplateElement = (org.w3c.dom.Element) iter.next();Properties templateProperties = new Properties();addTemplateProperty(mailTemplateElement, "actors", templateProperties);addTemplateProperty(mailTemplateElement, "to", templateProperties);addTemplateProperty(mailTemplateElement, "subject", templateProperties);addTemplateProperty(mailTemplateElement, "text", templateProperties);addTemplateProperty(mailTemplateElement, "bcc", templateProperties);addTemplateProperty(mailTemplateElement, "bccActors", templateProperties);templates.put(mailTemplateElement.getAttribute("name"), templateProperties);}templateVariables = new HashMap();List variableElements = XmlUtil.elements(mailTemplatesElement, "variable");iter = variableElements.iterator();while (iter.hasNext()) {org.w3c.dom.Element variableElement = (org.w3c.dom.Element) iter.next();templateVariables.put(variableElement.getAttribute("name"), variableElement.getAttribute("value"));}}return (Properties) templates.get(templateName);}void addTemplateProperty(org.w3c.dom.Element mailTemplateElement, String property, Properties templateProperties) {org.w3c.dom.Element element = XmlUtil.element(mailTemplateElement, property);if (element!=null) {templateProperties.put(property, XmlUtil.getContentText(element));}}String evaluate(String expression) {if (expression==null) {return null;}VariableResolver variableResolver = JbpmExpressionEvaluator.getUsedVariableResolver();if (variableResolver!=null) {variableResolver = new MailVariableResolver(templateVariables, variableResolver);}return (String) JbpmExpressionEvaluator.evaluate(expression, executionContext, variableResolver, null);}class MailVariableResolver implements VariableResolver, Serializable {private static final long serialVersionUID = 1L;Map templateVariables = null;VariableResolver variableResolver = null;public MailVariableResolver(Map templateVariables, VariableResolver variableResolver) {this.templateVariables = templateVariables;this.variableResolver = variableResolver;}public Object resolveVariable(String pName) throws ELException {if ( (templateVariables!=null)&& (templateVariables.containsKey(pName))){return templateVariables.get(pName);}return variableResolver.resolveVariable(pName);}}private static Log log = LogFactory.getLog(Mail.class); }/*** 郵箱認證類* @author royzhou* 2009.07.21*/ class MyAuthentication extends Authenticator {private String userName;private String password;public MyAuthentication(String userName, String password) {this.userName = userName;this.password = password;}protected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication(userName,password);} }

    下面我們開始寫我們的測試類:MailNode
    Java代碼 ?
  • package?com.royzhou.test; ??
  • ??
  • import?org.jbpm.graph.def.ProcessDefinition; ??
  • import?org.jbpm.graph.exe.ProcessInstance; ??
  • import?org.jbpm.graph.exe.Token; ??
  • ??
  • public?class?MailNode?{ ??
  • ???? ??
  • ????public?static?void?main(String[]?args)?{ ??
  • ????????ProcessDefinition?processDefinition?=?ProcessDefinition.parseXmlResource("mail/processDefinition.xml"); ??
  • ????????ProcessInstance?processInstance?=?new?ProcessInstance(processDefinition); ??
  • ????????processInstance.getContextInstance().setVariable("actorId",?"royzhou"); ??
  • ????????Token?token?=?processInstance.getRootToken(); ??
  • ????????token.signal(); ??
  • ????????System.out.println("end^^^^^^^^^^^^"); ??
  • ????} ??
  • }??
  • package com.royzhou.test;import org.jbpm.graph.def.ProcessDefinition; import org.jbpm.graph.exe.ProcessInstance; import org.jbpm.graph.exe.Token;public class MailNode {public static void main(String[] args) {ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("mail/processDefinition.xml");ProcessInstance processInstance = new ProcessInstance(processDefinition);processInstance.getContextInstance().setVariable("actorId", "royzhou");Token token = processInstance.getRootToken();token.signal();System.out.println("end^^^^^^^^^^^^");} }
    運行測試程序,后臺打印:
    enter mail node
    test====test
    leave mail node
    end^^^^^^^^^^^^

    打開你的收件箱發現郵件發送成功并且信息都是根據模版生成的。。


    至此,我們將流程的節點基本上都過了一遍。。。。 筆記終于寫完。。。累就一個字

    明天出差。。。。
    回來繼續。。。。。?

    總結

    以上是生活随笔為你收集整理的Jbpm 流程节点的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。