jbpm 入门实例(4)—— JBPM简单实例入门
1、新建项目 ?? 主菜单“文件->新建->项目”,在弹出的对话框里,选中JBoss jbpm节点下的“ Process Project ”项。输入项目名:JbpmProject,项目建好后结构如图所示: ???????
??? 这个项目和通常 Eclipse 的项目结构有点不同,不过? 这是一个现在非常流行的项目结构, src/java 存放源文件, test/java 存放相应的 JUnit 单元测试代码。 下面介绍一下各个文件: l???????? MessageActionHandler ,自动生成的一个 ActionHandler 。不想要可以删掉。 l???????? ehcache.xml? cache 的配置文件,里面有很详解的英文说明。没有必要可以不用改它。 l???????? hibernate.cfg.xml jBPM 是用 Hibernate 进行工作流的数据存储的,这个就是 Hibernate 的配置文件。后面我们将讲到如何配置这个文件。 l???????? jbpm.cfg.xml jbpm 本身的配置文件。现在是空的,它用的是缺省配置,你想知道有哪些配置就去看这个文件E:/software/jbpm-starters-kit-3.1.2/jbpm/src/java.jbpm/org/jbpm/default.jbpm.cfg.xml l???????? log4j.properties 这个是日志 API 包 log4j 的配置文件,用过 log4j 的都知道。 l???????? SimpleProcessTest.java 这个是对最重要的流程配置文件的 processdefinition.xml 单元测试代码。这里表扬一点, jBPM 的优良设计使得它的可测试性非常之高,喜欢写 t 单元测试的人有福了。 l???????? gpd.xml 用于生成流程图的定义文件。都是一些方框的坐标和长宽 l???????? processdefinition.xml 这个是对最重要的流程配置文件,以后写流程要经常和它打交道。 l???????? processimage.jpg 一个流程图 2、修改hibernate.cfg.cml配置文件 hibernate.cfg.xml 的默认设置是用 HSQL ,这是一个内存数据库,这种内存数据库用来代替项目实际所用的数据库来做单元测试挺不错的。 注:配置值可参考jbpm-starters-kit-3.1.2/jbpm-db 对应子目录下的 hibernate.properties 文件。 一、网上朋友给我mysql与oracle的配置如下: 1 、 MySQL 的更改如下: <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/jbpm</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123456</property>
?
2 、 Oracle 的更改如下: <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property> <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <property name="hibernate.connection.url">jdbc:oracle:thin:@192.168.123.10:1521:wxxrDB</property> <property name="hibernate.connection.username">chengang</property> <property name="hibernate.connection.password">chengang</property>
?
如果你装了 Oracle 的客户端,并且 D:/oracle/ora92/network/ADMIN/tnsnames.ora 里做了如下的设置 WXXRDB_192.168.123.10 = ? (DESCRIPTION = ??? (ADDRESS_LIST = ????? (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.123.10)(PORT = 1521)) ??? ) ??? (CONNECT_DATA = ????? (SID = wxxrDB) ????? (SERVER = DEDICATED) ? ) 则 Oracle 的 hibernate.connection.url 项也可以设为: jdbc:oracle:oci:@WXXRDB_192.168.123.10 二、我的配置修改 ?1、sqlserver <!-- hibernate dialect --> ??? <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
?
??? <!-- JDBC connection properties (begin) --> ??? <"hibernate.connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property> ??? <"hibernate.connection.url">jdbc:jtds:sqlserver://localhost:1433/jbpm</"hibernate.connection.username">sa</"hibernate.connection.password">admin</property> <!-- JDBC connection properties (end) --> 3、完善库引用 主要是把你所用的数据库的 JDBC 库引用进来,如果你是下载的jbpm-starters-kit-3.1.2可能还要把 Hibernate 的 hibernate3.jar 加入到项目的库引用中。 4、开始流程 这里是一个很简单的请假流程,请假人提交假单给经理审批,经理审批后结束。 1 、定义流程 流程的定义文件是 processdefinition.xml ,这个是一个关键文件, jBPM 的很大一部份内容都是关于它的。在这里我们把原来自动生成的内容,稍做改动: <?xml version="1.0" encoding="UTF-8"?>
?
<process-definition ? xmlns="urn:jbpm.org:jpdl-3.2" ? name="helloworld"> ? <!-- 申请 --> ?? <start-state "request"> ?? ??<task> ?? ??? ???<controller> ?? ??? ?????????<variable "name"/> ?? ??? ?????????<"day"/> ?? ??? ?????????<"note"/> ?? ??? ???</controller> ?? ??</task> ?? ??流程转向 --> ????? <transition "to_confirm" to="confirm"> ???????? <action "requestAction" class="com.stt.jbpm.RequestAction"> ??????????? <reason>我要请假</reason> ???????? </action> ????? </transition> ?? </start-state> ?? 审批state "confirm"> ????? <"to_end" "end"> ???? ????<"finishAction" "com.stt.jbpm.ConfirmAction"/> ????? </state> ?? 结束end-state "end"></end-state> </process-definition> 说明: 流程的名称改成了 helloworld 。(呵呵,也就是这里和 helloworld 有关了) <controller> 标签定义了三个数据:姓名、请假天数、说明。 <transition> 标签定了 request 节点的一个流程转向,这里是转到 confirm 节点。 <action> 标签定义了流程由一个节点转到另一个节点时,所要执行的动作,动作封装在一个 ActionHandler 类中。比如这里当 request 到 confirm 结点时将执行 RequestAction 类的 execute 方法。 RequestAction下面还有一个 <reason> (请假理由),它对应于RequestAction 的属性 String reason 。 5、编写 ActionHandler ??? 在上面 processdefinition.xml 里我们定义了两个 ActionHandler : RequestAction 、 ConfirmAction 。其代码如下: package com.stt.jbpm;
?
import org.jbpm.graph.def.ActionHandler; import org.jbpm.graph.exe.ExecutionContext;
?
public class RequestAction implements ActionHandler { ??? private static final long serialVersionUID = 1L; ??? ??? private String reason; ??? ??? @Override ??? void execute(ExecutionContext context) throws Exception { ?????? context.getContextInstance().setVariable("note",reason); ??? }
?
??? public String getReason() { ?????? return reason; ??? }
?
??? void setReason(String reason) { ?????? this.reason = reason; ??? }
?
} 说明: ExecutionContext 是一个贯通流程的容器。它是个大宝箱,里面啥玩意都有,后面将更深入的提到。这里的 reasion 就是 processdefinition.xml 中的 ” 我要请假 ” class ConfirmAction serialVersionUID = 1L; ??? ??? "准假"); ??? }
?
} 6、部署processdefinition.xml 我们要把 processdefinition.xml 的流程定义的数据部署到数据库中,因为 jBPM 在正式运行的时候不是去读 processdefinition.xml 文件,而是去读数据库中的流程定义。 ?? 这里写了一个个 JUnit 程序来部署 processdefinition.xml ,当然你用普通的 Java Main 也可以。 import junit.framework.TestCase;
?
import org.jbpm.JbpmConfiguration; import org.jbpm.JbpmContext; import org.jbpm.graph.def.ProcessDefinition;
?
/** ?* 流程部署 ?* @author USER ?* ?*/ class DeployProcessTest extends TestCase {
?
??? /** ??? ?本方法执行完毕后,检查jbpm_processdefinition表会多了一条记录 ??? ?@throws Exception ??? ?*/ ??? void testDeployProcess() throws Exception { ??????? //从jbpm.cfg.xml取得jbpm的配置 ?????? JbpmConfiguration config = JbpmConfiguration.getInstance(); ?????? 创建一个容器 ?????? JbpmContext jbpmContext = config.createJbpmContext(); ?????? 由processdifinition.xml生成相对应的流程定义类ProcessDefinition ?????? ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("simple/processdefinition.xml"); ??????? ?????? 利用容器的方法将流程定义数据部署到数据库上 ?????? jbpmContext.deployProcessDefinition(processDefinition); ?????? 关闭jbpmContext ?????? jbpmContext.close(); ??? } } 运行此程序,在控制台打印了一些日志,通过。如果出错,仔佃阅读出错信息以判断错误原因,并确定你按照前面两节:“修改 hibernate.cfg.xml ”和“完善库引用”的内容做好了设置。 报错: 14:44:50,921 [main] INFO? JpdlXmlReader : process xml information: no swimlane or assignment specified for task ' <task xmlns="urn:jbpm.org:jpdl-3.2" blocking="false" signalling="true" priority="normal" notify="false"> ?? ???????<!-- controller管理task变量 --> ?? ??? ???<controller config-type="field"> ?? ??? ?????????<variable name="name" access="read,write"/> ?? ??? ?????????<variable name="day" access="read,write"/> ?? ??? ?????????<variable name="note" access="read,write"/> ?? ??? ???</controller> ?? ??</task>' 14:44:55,765 [main] ERROR JDBCExceptionReporter : Table not found in statement [select top ? processdef0_.ID_ as ID1_0_,processdef0_.NAME_ as NAME3_0_,processdef0_.DESCRIPTION_ as DESCRIPT4_0_,processdef0_.VERSION_ as VERSION5_0_,processdef0_.ISTERMINATIONIMPLICIT_ as ISTERMIN6_0_,processdef0_.STARTSTATE_ as STARTSTATE7_0_ from JBPM_PROCESSDEFINITION processdef0_ where processdef0_.NAME_=? order by processdef0_.VERSION_ desc] 14:44:55,765 [main] ERROR GraphSession : org.hibernate.exception.SQLGrammarException: could not execute query 咋回事呢?查看hibernate.cfg.xml配置,原来中午修改的配置忘了保存。重新修改,再此运行,OK搞定。 到底成功了没呢? 7、从数据库中的查看部署效果 查询以下各表: |