子在川上曰

  逝者如斯夫不舍昼夜
随笔 - 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 陈刚 阅读(30934) 评论(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

只有注册用户登录后才能发表评论。


网站导航: