子在川上曰

            逝者如斯夫不舍晝夜
          隨筆 - 71, 文章 - 0, 評論 - 915, 引用 - 0
          數據加載中……

          jBPM開發入門指南(4)

          7   jBPM 的客戶端開發

          有了前面的 HelloWorld 后臺流程,我們就要開始客戶端程序了。正如前面提到的,本文不寫 JSP ,而改采用 JUnit 的形式,輸出則用 System.out.println 。舉一反三,知道在方法中輸入及用 println 輸出,在 JSP SWING GUI 界面還不是一樣嘛。

          ?

          這個 JUnit 客戶端,我們就借用創建項目時自動生成的 SimpleProcessTest.java 了,改寫后如下:

          package com.sample;

          ?

          import junit.framework.TestCase;

          ?

          import org.jbpm.JbpmConfiguration;

          import org.jbpm.JbpmContext;

          import org.jbpm.context.exe.ContextInstance;

          import org.jbpm.graph.def.ProcessDefinition;

          import org.jbpm.graph.exe.ProcessInstance;

          ?

          public class SimpleProcessTest extends TestCase {

          ?

          ??? private JbpmConfiguration config = JbpmConfiguration.getInstance();

          ??? private JbpmContext ctx = config.createJbpmContext();

          ??? // helloworld 對應于 jbpm_processdefinition 表的 name 字段值,也即 processdefinition.xml name

          ??? // 這個值得取比較耗時,實際項目里最好和“數據庫的 JDBC 連接”一樣,讓它共享,不要頻繁打開關閉。

          ??? private ProcessDefinition processDefinition = ctx.getGraphSession().findLatestProcessDefinition("helloworld");

          ?

          ??? public void testNewRequest() {

          ??????? long id = newRequest();

          ??????? System.out.println("id=" + id);

          ??????? checkNewRequest(id);

          ??????? confirmRequest(id);

          ??????? checkconfirmRequest(id);

          ??????? ctx.close();// 關閉 jbpm 容器

          ??? }

          ?

          ??? /**

          ??? ? * 創建一個請假單

          ??? ? *

          ??? ? * @return

          ??? ? */

          ??? private long newRequest() {

          ??????? // 創建一個新流程

          ??????? ProcessInstance pi = processDefinition.createProcessInstance();

          ??????? // 取得流程的數據環境

          ??????? ContextInstance ci = pi.getContextInstance();

          ??????? // 創建一張請假單

          ??????? ci.setVariable("name", " 陳剛 www.chengang.com.cn" );

          ??????? ci.setVariable("day", 2);

          ??????? assertEquals(null, ci.getVariable("note"));

          ??????? // 請假申請結束,轉到下一個流程結點

          ??????? pi.signal();

          ??????? return pi.getId();

          ??? }

          ?

          ??? /**

          ??? ? * 檢查請假單的數據

          ??? ? *

          ??? ? * @param id

          ??? ? */

          ??? private void checkNewRequest(long id) {

          ??????? // 從數據庫提取原流程

          ??????? ProcessInstance pi = ctx.loadProcessInstance(id);

          ??????? // 取得流程的數據環境

          ??????? ContextInstance ci = pi.getContextInstance();

          ??????? // 創建一張請假單

          ??????? assertEquals(" 陳剛 www.chengang.com.cn" , ci.getVariable("name"));

          ??????? assertEquals(Integer.valueOf(2), ci.getVariable("day"));

          ??????? assertEquals(" 我要請假 " , ci.getVariable("note"));

          ?

          ??????? // 當前是結點為 confirm

          ??????? assertEquals(pi.getRootToken().getNode().getName(), "confirm");

          ??????? // 流程還沒結束

          ??????? assertFalse(pi.hasEnded());

          ??? }

          ?

          ??? /**

          ??? ? * 審批陳剛的請假申請

          ??? ? *

          ??? ? * @param id

          ??? ? */

          ??? private void confirmRequest(long id) {

          ??????? ProcessInstance pi = ctx.loadProcessInstance(id);

          ??????? ContextInstance ci = pi.getContextInstance();

          ??????? // 不通過

          ??????? ci.setVariable("note", " 不準請假,繼續加班 " );

          ??????? // 審批結束,到下一個流程結點

          ??????? pi.signal();

          ??? }

          ?

          ??? private void checkConfirmRequest(long id) {

          ??????? ProcessInstance pi = ctx.loadProcessInstance(id);

          ??????? ContextInstance ci = pi.getContextInstance();

          ??????? // ConfirmAction 類在 signal 后執行,所以覆蓋了經理的審批意見

          ??????? assertEquals(" 準假 " , ci.getVariable("note"));

          ?

          ??????? // 當前是結點為 end

          ??????? assertEquals(pi.getRootToken().getNode().getName(), "end");

          ??????? // 流程結束了

          ??????? assertTrue(pi.hasEnded());

          ??? }

          ?

          }

          ?

          這個例子還是很簡單,而且關鍵是缺少用戶、組、權限等工作流系統必須的東西,不過沒關系。下面的內容我將完成一個更完整的實例。

          posted on 2006-08-24 18:15 陳剛 閱讀(30971) 評論(37)  編輯  收藏 所屬分類: jBPM

          評論

          # re: jBPM開發入門指南(4)   回復  更多評論   

          最近也再研究JBPM,謝謝樓主的文章,加油!
          2006-08-25 18:03 | 劉小偉

          # re: jBPM開發入門指南(4)   回復  更多評論   

          單元測試各個方法之間有依賴關系??
          2006-08-27 14:15 | pikachu

          # re: jBPM開發入門指南(4)   回復  更多評論   

          @pikachu
          為了簡潔和閱讀代碼的方便,這里沒有遵照單元測試的原則。比如你所說的方法之間的依賴性,還有對數據庫的依賴,這都是單元測試的大忌。如果是要寫真正的項目單元測試,jBPM的隨包文檔要更標準一些。
          2006-08-28 09:06 | 陳剛

          # re: jBPM開發入門指南(4)   回復  更多評論   

          如何將用戶、組、權限同流程點聯合起來,請說下你的思路好么?

          謝謝你的文章。繼續加油。
          2006-08-29 11:15 | ktm

          # re: jBPM開發入門指南(4)   回復  更多評論   

          @ktm
          后繼文章即將涉及
          2006-08-29 11:18 | 陳剛

          # re: jBPM開發入門指南(4)   回復  更多評論   

          附上中表的中文意思
          JBPM_ACTION action記錄表
          JBPM_DECISIONCONDITIONS 結果條件表
          JBPM_DELEGATION 委托表
          JBPM_EVENT 事件表 處理進入或者離開事件
          JBPM_EXCEPTIONHANDLER 異常處理表
          JBPM_ID_GROUP 用戶組表
          JBPM_ID_MEMBERSHIP 用戶成員表 表現用戶和組之間的多對多關系
          JBPM_ID_PERMISSIONS 用戶權限表
          JBPM_ID_USER 用戶表
          JBPM_MODULEDEFINITION 模塊定義表
          JBPM_MODULEINSTANCE 模塊實例表
          JBPM_NODE 流程節點表
          JBPM_POOLEDACTOR 匯集參與著表
          JBPM_PROCESSDEFINITION 流程定義表
          JBPM_PROCESSFILE 流程文件表
          JBPM_PROCESSFILEBLOCK 流程文件塊表
          JBPM_PROCESSINSTANCE 流程實例表
          JBPM_RUNTIMEACTION 運行中行為表
          JBPM_SCRIPTVARIABLES 腳本變量表
          JBPM_SWIMLANE 泳道表
          JBPM_SWIMLANEINSTANCE 泳道實例表
          JBPM_TASK 任務表
          JBPM_TASKACTORPOOL 用戶行為匯總
          JBPM_TASKINSTANCE 任務實例
          JBPM_TIMER 計時表
          JBPM_TOKEN 令牌表
          JBPM_TOKENVARIABLEMAP 令牌變量影射表
          JBPM_TRANSITION 轉換表
          JBPM_VARIABLEINSTANCE 變量實例表
          JBPM_VARIABLEINSTANCEBLOCK 變量實例塊表
          JBPM_VARIABLEMAPPING 變量影射表
          2006-08-29 11:29 | ktm

          # re: jBPM開發入門指南(4)   回復  更多評論   

          期待繼續!
          2006-08-29 16:10 | maya

          # re: jBPM開發入門指南(4)   回復  更多評論   

          Jbpm31DataModel%2FJBoss+jBPM+Definition+Data+Model
          哈哈。好東西。這個圖片
          http://wiki.jboss.org/wiki/attach?page=Jbpm31DataModel%2FJBoss+jBPM+Definition+Data+Model.png
          2006-08-30 16:27 | ktm

          # re: jBPM開發入門指南(4)   回復  更多評論   

          樓主加油啊!
          期待你的新作
          2006-08-31 19:59 | nianlu

          # re: jBPM開發入門指南(4)   回復  更多評論   

          @ktm
          非常感謝您提供的表說明
          2006-09-01 09:22 | 陳剛

          # re: jBPM開發入門指南(4)   回復  更多評論   

          最近也再研究JBPM,但是我有一個問題想和樓主討論下,
          如何將一個業務系統和JBPM相結合,個人淺見認為JBPM所提供的變量表的表結構不適合進行業務數據的各種組合查詢.所以我現在的做法是只將流程所涉及的業務主鍵ID存入JBPM變量表,再在業務系統相關表中存入processInstanceID & taskInstanceID進行流程定位,但是這樣做產生了在服務和JBPM間的一種看上去不是很好的一種關聯,致使在我在服務上要做JBPM的管理 以及 在需要時還要先查出業務主鍵集合再到業務系統中查出主鍵對應的實體信息.小弟學習不久可能做法有問題,希望能從樓主那得到開解!
          2006-09-02 18:48 | tom

          # re: jBPM開發入門指南(4)   回復  更多評論   

          陳大俠,您好!
          我是個JBPM的初學者,買過您ECLIPSE的書,之前也把您關于JBPM的入門指南等全看了好幾遍,我想問一下。。。如果我想要一個自己的JSP頁面,例如我要在頁面上放個下拉列表,放個表格,或者放個FLASH怎么辦。。。JBPM自帶的例子好象只有文本框。。。如果我放自己的東西他們應該怎么和JBPM內部對應起來呢。。。
          望大俠指教一二。。。。呵呵。。。
          2006-09-04 15:17 | gaok

          # re: jBPM開發入門指南(4)   回復  更多評論   

          這是人家的學習 ---Jboss JBPM 學習點滴
          (一)JBPM在Mysql 4.0以下運行有問題,主要是select語句的問題。
          (二)JBPM 數據庫默認的字符段是255個字符,有時需要修改,比如存儲文件的時候。JBPM數據庫默認的字段類型的定義有時候不一定適合需要,要手工進行修改。
          (三)對于工作流定義文件-processdifinition.xml的中文問題解決方案如下:
          (1)xml的Encoding設定成”GBK“
          (2)對于MySQL,hibernate相應的driver設定成:jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=GBK
          (3)文字在顯示的時候要用toGBK轉換才能正確顯示。
          (4)對于Oracle來講,Hibernate使用的C3P0連接池有問題,可用最新的C3P0代替。如果XML定義文件采用UTF8定義,顯示時可不用做GBK轉換。

          發來看看。可能對gaok有幫助
          2006-09-05 09:04 | ktm

          # re: jBPM開發入門指南(4)   回復  更多評論   

          @gaok
          JSP-->Servlet-->jBPM,Servlet里的寫法就參考本指南的寫法。
          2006-09-05 09:35 | 陳剛

          # re: jBPM開發入門指南(4)   回復  更多評論   

          15:55:56,109 [main] INFO SessionFactoryImpl : Checking 28 named queries
          15:55:56,640 [main] ERROR ErrorCounter : *** ERROR: line 4:47: unexpected token: t
          15:55:56,703 [main] ERROR ErrorCounter : *** ERROR: line 3:43: expecting "set", found 't'
          15:55:56,718 [main] ERROR ErrorCounter : *** ERROR: line 3:43: expecting "set", found 't'
          15:55:56,781 [main] ERROR ErrorCounter : *** ERROR: line 3:48: unexpected token: t
          15:55:56,812 [main] ERROR ErrorCounter : *** ERROR: line 4:33: unexpected token: m
          15:55:56,812 [main] ERROR SessionFactoryImpl : Error in named query: SchedulerSession.deleteTimersForProcessInstance
          org.hibernate.hql.ast.QuerySyntaxError: unexpected token: t near line 3, column 48 [

          delete from org.jbpm.scheduler.exe.Timer t
          where t.processInstance = :processInstance

          為什么部署的時候出現這個錯誤?
          2006-09-07 16:01 | chuanyuan

          # re: jBPM開發入門指南(4)   回復  更多評論   

          陳大哥。啥時候上第五章啊。。。

          乎乎·~
          2006-09-09 16:30 | ktm

          # re: jBPM開發入門指南(4)   回復  更多評論   

          例子中
          checkconfirmRequest(id); 應改為checkConfirmRequest(id);
          assertEquals(" 我要請假 " , ci.getVariable("note"));
          就改為:assertEquals("我要請假" , ci.getVariable("note"));
          2006-09-09 17:10 | zqh

          # re: jBPM開發入門指南(4)   回復  更多評論   

          期待你后續的文章
          2006-09-13 17:08 | 學習者

          # re: jBPM開發入門指南(4)   回復  更多評論   

          你好,
          我正在研究JBPM,看了您的文章很有啟發,
          不過我對于用戶,權限,以及怎樣和自己設計的JSP頁面統一還是不明白?能否就這方面多一點內容,十分感謝!
          2006-09-22 10:18 | ppxiaofei

          # 希望你能出書  回復  更多評論   

          希望陳大哥能出書。看網上的文章不是丟這,就是缺那。
          2006-11-21 10:16 | java愛好者[匿名]

          # re: jBPM開發入門指南(4)   回復  更多評論   

          你好! 我看了您的文章受益匪淺。
          我請教個問題,文章中設置流程實例變量(不知道這樣叫對不對)用的是方法
          ContextInstance ci = pi.getContextInstance();

          // 不通過

          ci.setVariable("note", " 不準請假,繼續加班 " );

          但是我看 jbpm的例子中使用的是如下方法:
          taskInstance.setVariable(taskFormParameter.getLabel(), taskFormParameter.getValue());
          這個應該和流程中的變量域有關吧? 是不是這個變量設置到 taskinstance這個范圍小一點的變量域中比較合適,contextinstance是不是全局都可見不是很好? 還是有參考的標準?
          2006-12-03 20:46 | lyo

          # re: jBPM開發入門指南(4)   回復  更多評論   

          @ktm
          那個ER圖什么工具設計的 ??
          2006-12-11 12:37 | 黃鵬霄[匿名]

          # re: jBPM開發入門指南(4)   回復  更多評論   

          期待下一章,大哥快上吧
          2006-12-21 11:03 | wala

          # re: jBPM開發入門指南(4)   回復  更多評論   

          我在使用你的客戶端的時候會出現異常
          pi = processDefinition.createProcessInstance();
          pi 為null
          這是那里的問題?
          2007-01-03 20:12 | horsezp

          # re: jBPM開發入門指南(4)   回復  更多評論   

          @chuanyuan
          http://www.jboss.org/?module=bb&op=viewtopic&p=3941594

          把jboss中的hibernate.jar & hibernate-matedata.jar 去掉,換上hibnernate3.1.jar以上的版本就行了
          我換上了3.2,行了。
          2007-01-18 17:23 | tony810428@hotmail.com

          # re: jBPM開發入門指南(4)   回復  更多評論   

          后臺測試是正常的,客戶端測試的時候出下面的錯誤
          junit.framework.AssertionFailedError: expected:<我要請假> but was:<null>
          2007-04-23 20:27 | yollywu

          # re: jBPM開發入門指南(4)   回復  更多評論   

          checkNewRequest(id);
          assertEquals(" 我要請假 " , ci.getVariable("note"));提示錯誤出在這兩處
          2007-04-23 21:53 | yollywu

          # re: jBPM開發入門指南(4)   回復  更多評論   

          package simple;
          import java.io.FileInputStream;
          import java.io.FileNotFoundException;
          import java.io.InputStream;

          import junit.framework.TestCase;

          import org.jbpm.JbpmConfiguration;
          import org.jbpm.JbpmContext;
          import org.jbpm.graph.def.ProcessDefinition;
          public class DeployProcessTest extends TestCase {
          /**
          * 在本方法執行完畢后,檢查 jbpm_processdefinition 表會多了一條記錄
          *
          * @throws FileNotFoundException
          */
          public void testDeployProcessDefinition() throws FileNotFoundException {
          // 從 jbpm.cfg.xml 取得 jbpm 的配置
          JbpmConfiguration config = JbpmConfiguration.getInstance();
          // 創建一個 jbpm 容器
          JbpmContext jbpmContext = config.createJbpmContext();
          // 由 processdefinition.xml 生成相對應的流程定義類 ProcessDefinition
          InputStream is = new FileInputStream("E:/eclipse/workspace/myjbpm/bin/simple/processdefinition.xml");
          ProcessDefinition processDefinition = ProcessDefinition.parseXmlInputStream(is);
          // 利用容器的方法將流程定義數據部署到數據庫上
          jbpmContext.deployProcessDefinition(processDefinition);
          // 關閉 jbpmContext
          jbpmContext.close();
          }

          public static void main(String arg[]){
          DeployProcessTest t = new DeployProcessTest();
          try{
          t.testDeployProcessDefinition();
          }catch(Exception e){
          e.printStackTrace();
          }


          }
          }


          程序執行到 ProcessDefinition processDefinition = ProcessDefinition.parseXmlInputStream(is);
          出現以下錯誤:

          15:58:30,625 [main] ERROR JpdlXmlReader : couldn't parse process definition
          org.dom4j.DocumentException: Error on line 2 of document : The processing instruction target matching "[xX][mM][lL]" is not allowed. Nested exception: The processing instruction target matching "[xX][mM][lL]" is not allowed.
          at org.dom4j.io.SAXReader.read(SAXReader.java:482)
          at org.jbpm.jpdl.xml.JpdlParser.parse(JpdlParser.java:57)
          at org.jbpm.jpdl.xml.JpdlXmlReader.readProcessDefinition(JpdlXmlReader.java:138)
          at org.jbpm.graph.def.ProcessDefinition.parseXmlInputStream(ProcessDefinition.java:172)
          at simple.DeployProcessTest.testDeployProcessDefinition(DeployProcessTest.java:24)
          at simple.DeployProcessTest.main(DeployProcessTest.java:34)
          Nested exception:
          org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed.
          at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1269)
          at org.dom4j.io.SAXReader.read(SAXReader.java:465)
          at org.jbpm.jpdl.xml.JpdlParser.parse(JpdlParser.java:57)
          at org.jbpm.jpdl.xml.JpdlXmlReader.readProcessDefinition(JpdlXmlReader.java:138)
          at org.jbpm.graph.def.ProcessDefinition.parseXmlInputStream(ProcessDefinition.java:172)
          at simple.DeployProcessTest.testDeployProcessDefinition(DeployProcessTest.java:24)
          at simple.DeployProcessTest.main(DeployProcessTest.java:34)
          org.jbpm.jpdl.JpdlException: [[FATAL] line 2: The processing instruction target matching "[xX][mM][lL]" is not allowed., [ERROR] couldn't parse process definition]
          at org.jbpm.jpdl.xml.JpdlXmlReader.readProcessDefinition(JpdlXmlReader.java:163)
          at org.jbpm.graph.def.ProcessDefinition.parseXmlInputStream(ProcessDefinition.java:172)
          at simple.DeployProcessTest.testDeployProcessDefinition(DeployProcessTest.java:24)
          at simple.DeployProcessTest.main(DeployProcessTest.java:34)
          請問是什么問題阿
          2007-07-09 16:17 | 小云

          # re: jBPM開發入門指南(4)   回復  更多評論   

          java.lang.NullPointException
          還有第41和71行有錯誤,
          為什么啊,有哪位大俠能夠告訴我啊!
          2007-08-17 18:35 | lxp

          # re: jBPM開發入門指南(4)   回復  更多評論   

          @horsezp
          我也是同樣的問題,你怎么解決的啊!
          2007-08-17 18:39 | lxp

          # re: jBPM開發入門指南(4)   回復  更多評論   

          ProcessInstance pi = processDefinition.createProcessInstance();
          ……
          long id = newRequest();

          NullPointerException異常!!
          換了hibernate3.1也不行
          2007-09-05 14:38 | liumingrui

          # re: jBPM開發入門指南(4)   回復  更多評論   

          強烈推薦去看看jboss seam里DvdStore的例子,是系統集成jbpm
          2008-06-05 10:37 | rock_soft

          # re: jBPM開發入門指南(4) [未登錄]  回復  更多評論   

          我現在迷糊了,要運行出什么樣的結果才是正確了呢?在JUnit面板中顯示Failures:1。那就是說失敗了吧,最后結果打印出了id=1. 如果運行成功了,效果是什么樣子的呢?
          2008-09-23 15:11 | 小鳥

          # re: jBPM開發入門指南(4) [未登錄]  回復  更多評論   

          呵呵,我知道為什么了。在這個地方assertEquals(" 我要請假 " , ci.getVariable("note"));,我要請假前后有空格,跟ci.getVariable("note"取的值不相等,所以就錯了。
          2008-09-23 15:25 | 小鳥

          # re: jBPM開發入門指南(4)   回復  更多評論   

          public void testNewRequest() { 方法出錯 請問怎么解決啊 急!!!!!!!!!!!!!!!
          2009-07-24 17:34 |

          # re: jBPM開發入門指南(4)   回復  更多評論   

          public void testNewRequest() { 方法出錯 請問怎么解決啊 急!!!!!!!!!!!!!!!
          2009-07-24 17:34 |

          # re: jBPM開發入門指南(4)   回復  更多評論   

          見教了,好容易入門,呵呵,希望還有更好的工作流例子,共享下
          2009-09-12 11:40 | zw7534313
          主站蜘蛛池模板: 南汇区| 柘荣县| 房产| 贵港市| 宁强县| 景德镇市| 吉林省| 丰原市| 西丰县| 瓦房店市| 泰宁县| 监利县| 萍乡市| 长兴县| 西丰县| 建德市| 崇文区| 响水县| 隆德县| 观塘区| 枝江市| 密山市| 泾阳县| 乐安县| 贡觉县| 桃江县| 铜陵市| 林芝县| 姜堰市| 巴南区| 安西县| 塔河县| 增城市| 新营市| 勃利县| 新沂市| 嘉兴市| 盘锦市| 柳河县| 白城市| 扎鲁特旗|