ssh2+jbpm3集成开发示范(二)

ssh2+jbpm3集成开发示例(二)

准备工作已经做好了,现在就可以开始进行代码的编写了。ssh框架集成的开始模式其实比较简单,各层的对象由spring负责管理,各层对象的依赖由spring负责注入。一般我们推荐采用面向接口的编程方式,理由很简单,大家都这么做。系统主要由数据访问层,业务层,控制层,显示层组成,当然根据具体情况可能会稍有不同,但只有能解决问题就可以了。其中由spring管理业务层的事务。

    1.DAO

package org.qhit.jbpm;

import java.util.List;
import java.util.Map;
import org.jbpm.taskmgmt.exe.TaskInstance;
import org.springframework.transaction.annotation.Transactional;

/**
 * 关于流程的数据访问接口
 *
 * @author 健坤IT教育
 *
 */
public interface MonthDaoI {

 /**
  * 发布流程[流程定义的打包文件的路径]
  */
 public abstract void publish(final String path);

 /**
  * 删除流程
  * @param pfid[流程定义ID]
  */
 public void deleteDefinition(final long pfid);

 /**
  * 完成任务
  * @param tasker
  * @param taskName
  * @param params
  * @param pid
  * @param tranName
  */
 public void finishTask(final String tasker, final String taskName,
   final Map params, final long pid, final String tranName);

 /**
  * 启动流程
  * @param pfid
  * @param params
  * @return
  */
 public long start(final long pfid, final Map params);

 /**
  * 查找未完成的任务列表
  * @param actorId
  * @return
  */
 public List<TaskInstance> getAllTaskByActorId(final String actorId);
}

实现类

package org.qhit.jbpm;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import org.jbpm.JbpmContext;
import org.jbpm.JbpmException;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.taskmgmt.exe.TaskInstance;
import org.springframework.transaction.annotation.Transactional;
import org.springmodules.workflow.jbpm31.JbpmCallback;
import org.springmodules.workflow.jbpm31.support.JbpmDaoSupport;

/**
 * spring注入jbpmtmplate或jbpmconfiguration对象
 *
 * @author 峰哥
 *
 */

public class MonthDao extends JbpmDaoSupport implements MonthDaoI {

 // 发布----
 /*
  * (non-Javadoc)
  *
  * @see org.qhit.jbpm.MonthDaoI#publish(java.lang.String)
  */
 public void publish(final String path) {

  super.getTemplate().execute(new JbpmCallback() {

   public Object doInJbpm(JbpmContext context) throws JbpmException {

    ZipInputStream in = new ZipInputStream(MonthDao.class
      .getResourceAsStream(path));
    ProcessDefinition pd = ProcessDefinition
      .parseParZipInputStream(in);
    context.deployProcessDefinition(pd);
    return null;
   }
  });
 }

 // 删除
 public void deleteDefinition(final long pfid) {

  super.getTemplate().execute(new JbpmCallback() {

   public Object doInJbpm(JbpmContext context) throws JbpmException {
    context.getGraphSession().deleteProcessDefinition(pfid);

    return null;
   }
  });
 }

 // 查找任务人所有未完成的任务
 public List<TaskInstance> getAllTaskByActorId(final String actorId) {
  return super.getTemplate().findTaskInstances(actorId);

 }

 // 启动流程[带流程变量]
 public long start(final long pfid, final Map params) {
  return (Long) super.getTemplate().execute(new JbpmCallback() {
   public Object doInJbpm(JbpmContext context) throws JbpmException {
    ProcessDefinition df = context.getGraphSession()
      .loadProcessDefinition(pfid);
    ProcessInstance pi = df.createProcessInstance(params);
    // 发信号
    pi.signal();
    return pi.getId();
   }
  });

 }

 // 完成任务----[任务人,任务名,数据,流程实例编号 转向名]
 public void finishTask(final String tasker, final String taskName,
   final Map params, final long pid, final String tranName) {

  super.getTemplate().execute(new JbpmCallback() {
   public Object doInJbpm(JbpmContext context) throws JbpmException {
    ProcessInstance pi = context.loadProcessInstance(pid);
    Collection<TaskInstance> taskes = pi.getTaskMgmtInstance()
      .getTaskInstances();
    if (taskes != null) {
     for (TaskInstance t : taskes) {
      if (!t.hasEnded() && t.getActorId().equals(tasker)
        && t.getName().equals(taskName)) {
       t.end(tranName);// 结束任务
       break;
      }
     }
    }
    return null;
   }
  });

 }

}

 

2.BIZ[业务层]

package org.qhit.jbpm.biz;

import java.util.List;
import java.util.Map;

import org.jbpm.taskmgmt.exe.TaskInstance;
import org.qhit.jbpm.MonthDaoI;
import org.springframework.transaction.annotation.Transactional;
@Transactional(readOnly=false)
/**
 * 流程处理的业务类
 */
public class MonthJbpmBiz {
 private MonthDaoI monthDao;
 public void setMonthDao(MonthDaoI monthDao) {
  this.monthDao = monthDao;
 }
 //发布
 public void publish(String path)
 {
  this.monthDao.publish(path);
  
 }
 //启动
 public long start(long  pfid,Map<String, Object> params)
 {
  return this.monthDao.start(pfid, params);
 }
 //完成任务
 public void finishTask(final String tasker,final String taskName,final Map params,final long pid,final String tranName)
 {
  
  this.monthDao.finishTask(tasker, taskName, params, pid, tranName);
 }
 //查找任务
 public List<TaskInstance> getAllTaskByActorId(final String actorId){
  return this.monthDao.getAllTaskByActorId(actorId);
 }

}
这里的业务比较简单,所以代码应该很容易弄懂,这里没有使用接口也是可以的,但代理方式就不是基于接口了,而是基于cglib方式。注意在业务方法中的异常处理,如果有异常,一定要把异常抛出来。否则spring可能无法知道是否发生异常,但从当发生异常里不rollback事务。

3.ACTION[控制层]

一般的项目开发中,很少让控制层直接处理由业务层抛出的异常,所有我们一般会在业务层与控制层加一层比如wrapper之类的,处理业务层可以出现的异常,然后返回友好的结果给控制层。但这仅仅是个简单的示例。我们就直接将业务层对象注入给控制层的action了。

package org.qhit.web.actions;

import java.util.List;

import org.jbpm.taskmgmt.exe.TaskInstance;
import org.qhit.jbpm.biz.MonthJbpmBiz;

import com.opensymphony.xwork2.util.ValueStack;
/**
 * 关于月度报表流程的控制类
 * 1.发布流程
 * 2.启动流程
 * 3.完成任务....
 * @author 峰哥 健坤教育---快乐学习
 *
 */
public class MonthAction {

 //spring di
 private MonthJbpmBiz monthJbpmBiz;

 private List<TaskInstance> taskes;//提供getter setter方法

 //spring注入业务对象
 public void setMonthJbpmBiz(MonthJbpmBiz monthJbpmBiz) {
  this.monthJbpmBiz = monthJbpmBiz;
 }
 
 private String actorId;//保存登陆后的用户名

 public List<TaskInstance> getTaskes() {
  return taskes;
 }

 public void setTaskes(List<TaskInstance> taskes) {
  this.taskes = taskes;
 }

 public String getActorId() {
  return actorId;
 }
 public void setActorId(String actorId) {
  this.actorId = actorId;
 }
 //查询
 public String findAll(){
  //ValueStack 【这里的任务参与人是硬编码的....】
  List<TaskInstance> taskes = this.monthJbpmBiz.getAllTaskByActorId("清华小帅哥");//这里是硬编码
  this.taskes = taskes;
  System.out.println("在action中取得任务列表:\t"+taskes);
  return "ok";
 }
 

}
4.jsp等[显示层]

ok.jsp  作用是遍历保存于作用域中的taskes变量,显示当前用户的所有任务列表。

<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%@ taglib  prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>


<c:forEach items="${taskes}" var="task">
 <div><a href="show.jsp?tid=${task.id }">${task.name }</a></div>
</c:forEach>

show.jsp  利用jbpm图形标记,显示当前流程实例的图形信息。

<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%@page import="org.jbpm.JbpmContext"%>
<%@page import="org.jbpm.JbpmConfiguration"%>
<%@ taglib prefix="jbpm" uri="/WEB-INF/jbpm.tld"%>


<jbpm:processimage task="${param.tid}"/>

基本的代码就是这些,下面的就是配置文件的编写与修改了。【未完待续】