最终篇
一、该版本将完成一个比较完整的系统
1.修改上传界面,此次上传一个zip文件,包括流程定义文件、流程定义图片、流程定义文件坐标文件,后两个文件对动态查看流程的状态有效!
所以处理上传的内容也有所变动,具体看deployProcessDefinition.jsp文件
上传zip的处理:
其实上传zip包后部署的时候,JBPM首先会在jbpm_moduledefinition表中保存一个FileDefinition对象
(如果上传的不是zip格式的那么FileDefinition对象就为空),
也就是说这个对象封装的是zip包中的三个文件,然后JBPM会从这个对象中将一个个的文件拆分出来,
分别都保存到jbpm_bytearray表中,而三个文件中的数据内容并没有保存在jbpm_bytearray表中,
而是保存到了jbpm_byteblock表中,这样就完成了对zip格式的文件部署!
(当然也会在jbpm_processdefinition表中保存流程定义文件的内容)
**注意:其实流程定义文件不是必须要存储到数据库的,默认是存到数据库,如果不想存到数据库,
那么可以在jbpm.cfg.xml配置文件中加一个配置来指定将流程定义文件保存到哪个文件夹!!
<string name="jbpm.files.dir" value="d:/" />
通过value指定保存的目录名称!
2.我们之前的每个界面都要先通过JbpmConfiguration.getInstance().createJbpmContext()来获得JbpmContext对象,
而且要在最后调用JbpmContext.close()方法来关闭JbpmContext对象
解决麻烦:
为了方便JBPM为我们提供了一个Filter,对于指定的映射地址的请求,
该Servlet会通过先通过JbpmConfiguration对象产生一个JbpmContext对象,
当请求结束后JBPM会自动关闭刚刚创建产生的JbpmContext对象,
这样就省去我们自己createJbpmContext()了,也省去了我们自己close()了。
配置方法:加入到web.xml文件(可看源代码,很简单)
<filter>
<filter-name>JbpmContextFilter</filter-name>
<filter-class>org.jbpm.web.JbpmContextFilter</filter-class>
</servlet>
<filter-mapping>
<filter-name>JbpmContextFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
说明:这里是对所有的.jsp的请求做处理,这个映射只是为了适应我的当前项目。
也就是当请求所有的jsp的时候JBPM会先自动创建一个JbpmContext对象,
当jsp响应结束(可认为jsp页面关闭时)后JBPM会自动关闭JbpmContext对象
获得JBPM创建好的JbpmContext对象的方法:这样就得到了JBPM自己可以维护的JbpmContext对象!
JbpmContext jbpmContext = JbpmConfiguration.getInstance().getCurrentJbpmContext();
3.因为考虑到JbpmConfiguration这个对象比较耗费资源,所以在应用关闭的时候应该把JbpmConfiguration对象同时也要关闭
解决方法:为此JBPM为我们提供了一个Servlet类,该类内部非常简单(可看源码),
只有destroy()方法中加入了对JbpmConfiguration对象的close()方法。
所以该servlet没有必要配置映射地址,即不须指定<servlet-mapping>,
因为只需要应用启动时同时启动该Servlet,当应用关闭是会调用Servlet的destroy()方法,
这样就同时关闭了JbpmConfiguration对象
实现方法:配置到web.xml文件
<servlet>
<servlet-name>CloseJbpmConfigurationServlet</servlet-name>
<servlet-class>org.jbpm.web.CloseJbpmConfigurationServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
4.该项目中可能不止只有一个流程定义,所以要有一个界面来显示所有不同的流程定义类别,
也就是相当于我们办理某个流程的时候要先选择适合我们需要的流程。见listLatestProcessDefinitions.jsp文件
通过JbpmContext.getGraphSession().findLatestProcessDefinitions()方法得到所有的不同的流程定义文件的最新版本!
5.导出流程定义的功能:当显示指定的流程定义的所有版本的时候,会有一个导出的操作。此操作会要一个Servlet的支持!
也就是当点击导出的时候去请求指定的Servlet
Servlet的作用:根据流程定义的id值把流程定义取出来,然后取出每个文件(共三个),然后打包,最后下载
注意:详情见ExportProcessDefinition.java和web.xml中的配置
记住要设置响应给浏览器的内容类型response.setContentType("application/x-zip-compressed");
还要记住设置使用下载对话框的头信息response.setHeader("Content-Disposition", "attachment;filename=/"" + zipFileName +"/"");
6.加一个查看流程图(状态)的功能:还是在listProcessDefinitionVersions.jsp中加一个链接,然后请求一个Servlet。
所以要添加一个GetProcessImageServlet.java
Servlet的作用:和ExportProcessDefinition的功能差不多,只不过这里是只拿出流程定义图片,然后输出到浏览器
注意:记得要设置响应给浏览器的内容类型response.setContentType("image/jpeg");
7.增加删除流程定义功能,还是在listProcessDefinitionVersions.jsp中加一个链接,
请求removeProcessDefinition.jsp页面
注意:
这里如果删除了指定的流程定义记录那么代表着JBPM也会同时删除已经通过该流程定义文件启动的所有的流程实例对象,
所以该操作应该慎重操作,以免造成不必要的麻烦后果,按理说是如果存在以该流程定义文件启动的流程(流程对象),
那么该流程定义文件记录就不能删除!我们可以加入一些判断来实现。
8.我们现在的查看流程定义是查看所有的最新的流程定义列表,我们也可以通过一个流程定义名称来查看指定的流程定义信息,
我们可以自己写查询语句到JBPM提供的数据库中查询。
例如"from ProcessDefinition where name = ?"等,项目中没有做,不过我们可以自己再实现一下!
9.根据流程定义查询出所有的已经存在的对应的流程实例对象列表!!还是在listProcessDefinitionVersions.jsp中加一个链接,
具体见listProcessInstances.jsp
**10.流程跟踪的实现:一定要仔细阅读ProcessImageTag、jbpm.tld和ProcessImageServlet这三个文件中的内容!!
JBPM提供的支持源文件:
可到jbpm-starters-kit-3.1.2.zip包中的文件夹中拷贝源文件到项目中,用来代替我们自己的!我们可以自己修改!
- 从jbpm/src/java.webapp/org/jbpm/webapp/tag中拷贝ProcessImageTag.java文件
- 从jbpm/src/resources/jbpm.war/WEB-INF中拷贝对ProcessImageTag标签类的支持配置文件jbpm.tld文件到WEB-INF目录
- 从jbpm-starters-kit-3.1.2/jbpm/src/java.webapp/org/jbpm/webapp/servlet中拷贝ProcessImageServlet.java文件
功能解释:
就是对于没有结束的流程实例,通过流程跟踪可以查看当前流程实例的流程流转到了那个节点,
通过流程定义图片和流程定义坐标文件实现,我们可以在图上清晰的查看到流程实例的流程状态,即实现了流程跟踪!!
具体实现:
<1>首先将拷贝的Servlet配置到项目的web.xml配置文件中,以便Servlet起作用
<servlet>
<servlet-name>ProcessImageServlet</servlet-name>
<servlet-class>自己的包名.ProcessImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ProcessImageServlet</servlet-name>
<!--该映射地址不能变,因为这是JBPM实现时的配置,当然如果知道怎么回事可以自己修改
不过应该还要修改ProcessImageTag和jbpm.tld文件-->
<url-pattern>/processimage</url-pattern>
</servlet-mapping>
<2>页面中首先用<taglib>导入标签uri------taskInstanceId是当前任务就是要用红框框起来的任务所在节点!!
然后使用<jbpm:processImage task="${taskBean.taskInstanceId}"/>就会把流程图显示在当前位置
实现是会遇到的问题:
<1>因为JBPM自己实现时使用了JbpmContextFilter来创建和关闭JbpmContext对象,
所以ProcessImageTag和ProcessImageServlet中得到JbpmContext对象的方式
都是调用的JbpmConfiguration.getInstance().getCurrentJbpmContext()方法。
问题:如果我们使用了Spring和JBPM集成,那么这两个文件获得JbpmContext对象的方式都要进行修改!
解决方案:将JbpmContext的获取方式做一下修改就可以!改成从Spring中获得!
<2>乱码问题:因为流程定义文件不能很好的支持中文,尤其是gpd.xml文件,这个是流程定义坐标文件,
如果流程定义文件中使用了中文,那么跟踪定位时可能会出错也可能会出乱码!
例如:如果你的流程定义中用中文字符,数据库字符集为utf-8,
并且数据库中也确实为正确的utf-8内容,也可能会乱码错误。出乱码的文件更可能是gpd.xml文件
分析:
A.可能会出现空指针异常,是因为上下文的Element root中的字符为乱码。
- 出错的行为:result[0] = Integer.valueOf(node.attribute("x").getValue());
- 解决方案:将值用utf-8转码!
源码:Element rootDiagramElement = DocumentHelper.parseText(new String(gpdBytes)).getRootElement();
修改:Element rootDiagramElement = DocumentHelper.parseText(new String(gpdBytes, "utf-8")).getRootElement();
B.要注意ProcessImageTag.java文件中有一个请求ProcessImageServlet的操作并且传过去一个definitionId参数值,
我们要注意的就是该请求是"相对路径"还是"绝对路径",这要和我们的需求的具体情况核对后然后才能修改!!
注意:ProcessImageTag是一个java文件,那么从他中发送请求的相对路径又是相对与谁说的呢?
这里我们要特别注意,因为这是一个标签类,所以肯定是在一个jsp页面中使用该标签类对应的标签,
当标签运行的时候,该类中的代码才会运行,
所以相当于ProcessImageTag类中的代码是在那个使用标签的jsp页面中运行一样,
并且运行造成的结果也将会对那个使用标签的jsp页面有效,
所以所谓的相对路径就是那个使用对应该标签类的标签的jsp页面的相对路径,
即相对路径就是那个使用标签的jsp页面所在的路径!!(注意理解)
11.可以加入显示任务实例对象的列表(类似显示流程实例对象列表),也就是再加一个页面,
来根据指定的“流程名称”、“任务名字”或者“任务的参与者即actor-id”等值进行查询,当然还是到jbpm_taskinstance表中查询
(具体我没有实现,因为不太复杂,这里提供个思路,以后用到的话应该很容易能够实现)
12.我们可以通过对任务记录的create和start和end字段的值进行有价值的利用,就是我们可以对登陆人员添加"代办任务列表"和"代签收任务列表"
所谓代办任务列表就是end字段的值为空的任务记录,代签收任务列表的意思就是create字段的值已经生成,
而start字段中的值却没有,当点击签收的时候此时向start字段加入值也就是调用taskInstance的start()方法。
具体获得数据列表的方法:我们可以通过Hibernate的hql语句自己定制需求,到JBPM提供我们的数据库表中查得能满足我们需求的记录列表
(该项目中目前没有实现该功能,如果实现并不难)
13.如果想看更具体的内部实现可以常识看源代码:
我看过的类有:
JbpmConfiguration
JbpmContext
ProcessDefinition
ProcessInstance
Services
Service
TaskInstance
GraphSession
TaskMgmtSession
Node
Token
ExecutionContext
等等……
经过这十一个小项目,大家应该基本能够理解JBPM的内核实现及原理!如有发现项目中的错误或不恰当的地方欢迎留言批评。
该项目仍然是到下载频道下载。