一、 环境配置
基础环境是eclipse3+myeclipse6+mysql5+tomcat6 。
首先从网站上下载jBPM开发包(jbpm-jpdl-suite-3.2.3.zip),据说现在jBPM3已经升到3.2.6了,而且据说已经推出了jBPM4了。将jbpm-jpdl-suite-3.2.3.zip解压缩后,里面有个\designer文件夹,这个是eclipse IDE的jBPM插件,是可视化的那种。
安装这个插件:
1、 HelpSoftware Updates
2、 Find and Install Search for new features to install
3、 点击 New Local Site,选择jBPM开发包解压缩后的那个插件的地址,例如D:\jbpm-jpdl-3.2.3\designer
4、 一路点击Next就可以了,安装完成后,eclipse需要重启。重启后,可以在project中到到一个JBoss jBPM的项目。如图所示。
二、 设置一个User Library
很多人不习惯Process Project的那种代码结构,而我也不习惯。Process Project 的结构如图所示。
于是想给它设置一个自己的库,可以随时在各种WEB应用中调用。设置User Library的步骤如下:
1、 eclipse中,点击WindowPreferences
2、 JavaUser Library
3、 点击New,设置User Library name 为jBPM Library。点击OK。
4、 点击Add JARs,首先来到jBPM解压缩后的路径(例如:D:\jbpm-jpdl-3.2.3),有两个JAR,其中jbpm-jpdl.jar是一定要加的。
5、 还有其他的JARs要加,重复步骤4,进入lib包(例如:D:\jbpm-jpdl-3.2.3\lib),选中所有的JARs。
6、 这样,我们的jBPM Library就设置好了。如图所示:
三、 一个结合Struts 1.x的应用
首先,假定一个流程。这个流程是常用的报销流程,只考虑了最简单的流程。
角色有三种:普通员工(employee)、经理(manager)、BOSS(boss)。这里因为只是做个示例,没有考虑过多的权限方面的设置。这里设计了三个用户,分别对应了三种角色,并且员工有上级(经理)无下属、经理有上级(BOSS)有下属(员工)、BOSS无上级有下属(经理)。具体参看数据库设计。
好了,数据设计好了,开始搭建系统吧。步骤如下:
1、 FileNewWeb Project
2、 给新添加的web项目添加Struts 1.x类库。
3、 添加新的User Library,将刚才设置好的jBPM Library添加进来。
4、 在项目下新增一个Source Folder,命名为jbpm。
搭建好的结构如下图所示:
项目的流程定义文件和jBPM插件生成的图片在com.flowdemo.jbpm.expense包下。hibernate.cfg.xml配置文件需要做一些修改,原本配置的数据库连接是hsqldb。现在把它改成为连接MySQL。具体的配置信息查看代码清单。
Com.flowdemo.service包中包含有两个业务逻辑类,一个是关于对象持久化的:PersistenceService.java 一个是工作流的:FlowService.java 。
以下是PersistenceService.java源代码,主要是对持久化对象的一些操作。
package com.flowdemo.service;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import com.flowdemo.po.Expenses;
import com.flowdemo.po.Users;
import com.flowdemo.util.HibernateSessionFactory;
public class PersistenceService {
/**
* 保存一个报销单对象
* @param expense
*/
public static void save(Expenses expense){
Session hibernateSession = HibernateSessionFactory.getSession();
try{
//hibernateSession.getTransaction().begin();
hibernateSession.beginTransaction();
hibernateSession.saveOrUpdate(expense);
hibernateSession.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
hibernateSession.getTransaction().rollback();
}finally{
HibernateSessionFactory.closeSession();
}
}
/**
* 更新一个报销单对象
* @param expense
*/
public static void update(Expenses expense){
Session hibernateSession = HibernateSessionFactory.getSession();
try{
//hibernateSession.getTransaction().begin();
hibernateSession.beginTransaction();
//hibernateSession.saveOrUpdate(expense);
hibernateSession.update(expense);
hibernateSession.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
hibernateSession.getTransaction().rollback();
}finally{
HibernateSessionFactory.closeSession();
}
}
/**
* 删除一个报销单对象
* @param expense
*/
public static void delete(Expenses expense){
Session hibernateSession = HibernateSessionFactory.getSession();
try{
//hibernateSession.getTransaction().begin();
hibernateSession.beginTransaction();
hibernateSession.delete(expense);
hibernateSession.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
hibernateSession.getTransaction().rollback();
}finally{
HibernateSessionFactory.closeSession();
}
}
/**
* 返回一个报销单列表
* @return
*/
public static List<Expenses> getExpenses(){
Session hibernateSession = HibernateSessionFactory.getSession();
List<Expenses> expenses = new ArrayList<Expenses>();
try{
//hibernateSession.getTransaction().begin();
hibernateSession.beginTransaction();
//hibernateSession.delete(expense);
Query query = hibernateSession.createQuery("from Expenses");
expenses = query.list();
hibernateSession.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
hibernateSession.getTransaction().rollback();
}finally{
HibernateSessionFactory.closeSession();
}
return expenses;
}
/**
* 根据用户ID返回一个对象
* @param userId
* @return
*/
public static Users getUserById(String userId){
Session hibernateSession = HibernateSessionFactory.getSession();
Users user = new Users();
try{
hibernateSession.beginTransaction();
user = (Users)hibernateSession.get(Users.class, userId);
hibernateSession.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
hibernateSession.getTransaction().rollback();
}finally{
HibernateSessionFactory.closeSession();
}
return user;
}
/**
* 检查用户是否存在
* @param user
* @return
*/
public static boolean checkUser(Users user){
Users user2 = null;
try{
user2 = getUserById(user.getUserId());
System.out.println("用户的值==="+user2.getUserName());
}catch(Exception e){
e.printStackTrace();
}finally{
//HibernateSessionFactory.closeSession();
}
if(user2.getUserPass() == user.getUserPass() || user2.getUserPass().equals(user.getUserPass())){
return true;
}else{
return false;
}
}
/**
* 测试主方法
* @param args
*/
public static void main(String[]args){
Session hibernateSession = HibernateSessionFactory.getSession();
System.out.println("测试Session是否启动1"+hibernateSession.toString());
hibernateSession.close();
System.out.println("测试Session是否启动2"+hibernateSession.toString());
hibernateSession = HibernateSessionFactory.getSession();
System.out.println("测试Session是否启动1"+hibernateSession.toString());
HibernateSessionFactory.closeSession();
System.out.println("测试Session是否启动2"+hibernateSession.toString());
Users user = new Users();
user.setUserId("001");
user.setUserPass("employee");
boolean flag = checkUser(user);
System.out.println("是否是正确的?"+flag);
}
}
以下是FlowService.java源代码:
package com.flowdemo.service;
import java.util.ArrayList;
import java.util.List;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.db.GraphSession;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.taskmgmt.exe.TaskInstance;
import com.flowdemo.jbpm.util.PoTaskWrapper;
import com.flowdemo.po.Expenses;
import com.flowdemo.po.Users;
import com.flowdemo.util.HibernateSessionFactory;
public class FlowService {
static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
/**
* 初始化流程
*/
public static void initJbpm(){
JbpmContext jbpmContext = jbpmConfiguration.getCurrentJbpmContext();
if(jbpmContext == null || jbpmContext.equals("")){
jbpmContext = jbpmConfiguration.createJbpmContext();
}
//如果流程定义没有,则重新部署
try{
ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("com/flowdemo/jbpm/expense/processdefinition.xml");;
//测试是否存在
System.out.println("流程定义是否加载?==="+processDefinition.toString());
jbpmContext.deployProcessDefinition(processDefinition);
GraphSession graphSession = jbpmContext.getGraphSession();
processDefinition = graphSession.findLatestProcessDefinition("expense");
}finally{
jbpmContext.close();
}
}
/**
* 绑定报销单到流程中
*/
public static void bindingExpenseToProcess(){
JbpmContext jbpmContext = jbpmConfiguration.getCurrentJbpmContext();
if(jbpmContext == null || jbpmContext.equals("")){
jbpmContext = jbpmConfiguration.createJbpmContext();
}
try{
jbpmContext.setSessionFactory(HibernateSessionFactory.getSessionFactory());
ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition("expense");
ProcessInstance processInstance = new ProcessInstance(processDefinition);
jbpmContext.save(processInstance);
long processInstanceId = processInstance.getId();
//用什么来get or load这个Expenses对象呢?
Expenses expense = (Expenses)jbpmContext.getSession().createQuery("from Expenses where processInstanceId = "+null).list().get(0);
//Expenses expense = (Expenses)jbpmContext.getSession().get(Expenses.class, 3);
expense.setProcessInstanceId(new Long(processInstanceId).toString());
jbpmContext.getSession().update(expense);
processInstance.getContextInstance().setVariable("expense_id", expense.getExpenseId());
processInstance.signal();
}finally{
jbpmContext.close();
}
}
/**
* 根据用户来返回自己需要处理的任务
* @param user
* @return
*/
public static List getTasks(Users user){
JbpmContext jbpmContext = jbpmConfiguration.getCurrentJbpmContext();
if(jbpmContext == null || jbpmContext.equals("")){
jbpmContext = jbpmConfiguration.createJbpmContext();
}
System.out.println("提供任务的人的名字"+user.getUserName());
List tasks = new ArrayList();
//List expenses = new ArrayList();
List poAndTasks = new ArrayList();
try{
tasks = jbpmContext.getTaskMgmtSession().findTaskInstances(user.getUserName());
System.out.println("需要处理的任务的多少"+tasks);
TaskInstance taskInstance = null;
Expenses expense = null;
for(int i=0;i<tasks.size();i++){
taskInstance = (TaskInstance)tasks.get(i);
Integer expenseId =(Integer)taskInstance.getProcessInstance().getContextInstance().getVariable("expense_id");
System.out.println("expenseId的值是多少呢?"+expenseId);
PoTaskWrapper poTask = new PoTaskWrapper();
jbpmContext.setSessionFactory(HibernateSessionFactory.getSessionFactory());
expense = (Expenses)jbpmContext.getSession().load(Expenses.class, expenseId);
System.out.println("对应的报销单的编号、金额和理由"+expense.getExpenseId()+" "+expense.getMoney()+" "+expense.getReason());
//expenses.add(expense);
poTask.setExpense(expense);
System.out.println("poTask获得的expense-->"+poTask.getExpense().getMoney());
poTask.setTaskInstanceId(taskInstance.getId());
poTask.setTokenId(taskInstance.getToken().getId());
poAndTasks.add(poTask);
}
}catch(Exception e){
e.printStackTrace();
}finally{
jbpmContext.close();
}
//return expenses;
System.out.println("队列的长度 -->"+poAndTasks.size());
return poAndTasks;
}
/**
* @param processInstanceId
* @return
*/
public static boolean managerApprove(String processInstanceId){
JbpmContext jbpmContext = jbpmConfiguration.getCurrentJbpmContext();
if(jbpmContext == null || jbpmContext.equals("")){
jbpmContext = jbpmConfiguration.createJbpmContext();
}
try{
ProcessInstance processInstance = jbpmContext.getProcessInstance(new Long(processInstanceId).longValue());
//ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition("expense");
//ProcessInstance processInstance = new ProcessInstance(processDefinition);
TaskInstance taskInstance = processInstance.getTaskMgmtInstance().createTaskInstance();
taskInstance.end();
processInstance.signal();
}catch(Exception e){
e.printStackTrace();
}finally{
jbpmContext.close();
}
return false;
}
/**
* 审核
* @param taskInstanceId
*/
public static void approve(long taskInstanceId){
JbpmContext jbpmContext = jbpmConfiguration.getCurrentJbpmContext();
if(jbpmContext == null || jbpmContext.equals("")){
jbpmContext = jbpmConfiguration.createJbpmContext();
}
try{
TaskInstance taskInstance = jbpmContext.getTaskInstance(taskInstanceId);
//taskInstance.end("manager_approve");
taskInstance.end();
//processInstance.signal();
}catch(Exception e){
e.printStackTrace();
}finally{
jbpmContext.close();
}
}
}
还有一点需要注意的是,在测试运行之前需要把jbpm的数据库表创建好,当然也可以通过JbpmContext jbpmContext = cfg.createJbpmContext();来创建,但是这是在每次运行时都会创建,所以还是直接通过导入jbpm的sql文件来创建的好。
好了,一个基于struts的jbpm应用差不多就完成了,我比较懒,所以也不太想在介绍代码上费功夫了,各位看官自己看咯,呵呵。
还想做一些集成spring的应用,但是由于公司也没用上这种技术,所以兴趣又降了一大半,⊙﹏⊙b汗。以后有机会再自己写写吧。以下附上源代码。有需要的请下载吧。按照习惯,我去掉了jar包,所有的需要的jar清单,请看图片: