目錄
簡(jiǎn)
述
使
用jbpm-starters-kit-3.1.4生成數(shù)據(jù)庫(kù)表及安裝eclipse圖形化配置插件
部
署jbpm的jar包和moudle的jar包
部
署hbm文件到項(xiàng)目
設(shè)
置大字段string-max
配
置configration、template
過
濾器的設(shè)置與建立
編
寫發(fā)布流程定義xml的人機(jī)頁面及程序
寫
在最后
簡(jiǎn)述
Jbpm工作流框架與現(xiàn)有ssh框架的集成工作其
實(shí)很簡(jiǎn)單,但國(guó)內(nèi)外的資料太小,所以會(huì)在集成時(shí)走入太多誤區(qū),本文是在struts1.2,spring2.5,hibernate3.2上集成成功的詳細(xì)步驟。其中解決了,jbpm的訪問數(shù)據(jù)庫(kù)session與原有hibernate的session不同的問
題,string-max大字段問題。完成了流程部署web及后臺(tái)程序。利用spring-modules-0.8當(dāng)中的spring31做為集成
的橋梁(其實(shí)它已經(jīng)做好了集成,但文檔和實(shí)例實(shí)在是太簡(jiǎn)單)。
使用jbpm-starters-kit-3.1.4生成數(shù)據(jù)庫(kù)表及安裝eclipse圖形化配置插件
1下載jbpm-starters-kit-3.1.4到其網(wǎng)站,包含所有需要的工具及jar包。
2數(shù)據(jù)庫(kù)的安裝以oracle為例,其它
數(shù)據(jù)庫(kù)可按此例修改。
2.1創(chuàng)建所需用戶及表空間,如果有了用戶和表空間就不需要了。
2.2 找到jbpm-starters-kit-3.1.4文件夾,在其下的jbpm文件夾的下級(jí)文件夾lib中加入oracle的驅(qū)動(dòng)包ojdbc14.jar.
2.3 在jbpm"src"resources文件夾下建立oracle文件夾,將"jbpm"src"resources"hsqldb里的create.db.hibernate.properties和identity.db.xml文件copy到剛剛建立的oracle文件夾當(dāng)中.
2.4 修改create.db.hibernate.properties文件,修改目標(biāo)數(shù)據(jù)庫(kù)的連接屬性如下:
# these properties are
used by the build script to create
# a hypersonic database
in the build/db directory that contains
# the jbpm tables and a
process deployed in there
hibernate.dialect=org.hibernate.dialect.OracleDialect
hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver
hibernate.connection.url=jdbc:oracle:thin:@10.62.1.12:1521:oracle
hibernate.connection.username=dpf
hibernate.connection.password=dpf
hibernate.show_sql=true
hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
2.5 修改jbpm"src"config.files"hibernate.cfg.xml文件,同樣是配置數(shù)據(jù)庫(kù)的連接屬性如下:
<!--
jdbc connection properties -->
<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:@10.62.1.12:1521:oracle</property>
<property
name="hibernate.connection.username">dpf</property>
<property
name="hibernate.connection.password">dpf</property>
<property
name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
2.6 修改jbpm"build.deploy.xml文件.找到create.db項(xiàng)并進(jìn)行如下修改:
<!--
============== -->
<!--
=== SERVER === -->
<!--
============== -->
<target
name="create.db" depends="declare.jbpm.tasks, db.clean, db.start"
description="creates a hypersonic database with the jbpm tables and
loads the processes in there">
<jbpmschema
actions="create"
cfg="${basedir}/src/config.files/hibernate.cfg.xml"
properties="${basedir}/src/resources/oracle/create.db.hibernate.properties"/>
<loadidentities
file="${basedir}/src/resources/oracle/identity.db.xml"
cfg="${basedir}/src/config.files/hibernate.cfg.xml"
properties="${basedir}/src/resources/oracle/create.db.hibernate.properties"/>
<ant
antfile="build.xml" target="build.processes" inheritall="false" />
<deployprocess
cfg="${basedir}/src/config.files/hibernate.cfg.xml"
properties="${basedir}/src/resources/oracle/create.db.hibernate.properties">
<fileset
dir="build" includes="*.process" />
</deployprocess>
<antcall
target="db.stop" />
</target>
2.7 配置ant,在jbpm目錄執(zhí)行 ant create.db –buildfile build.deploy.xml命令。
會(huì)有一些小錯(cuò)誤的提示,沒有關(guān)系數(shù)據(jù)庫(kù)的表已經(jīng)建立完成。
2.8 eclipse的圖形化配置插件安裝文件可以到jbpm-starters-kit-3.1.4"jbpm-designer"
jbpm-gpd-feature"eclipse下找到,需注意版本。
部署jbpm的jar包和moudle的jar包
1 把如下jar包放入"WEB-INF"lib文件夾下,spring-modules-jbpm31.jar可以在
spring-modules-0.8下找到,其它的都屬于jbpm工具包。
bsh-1.3.0.jar
bsf.jar
spring-modules-jbpm31.jar
jbpm-webapp-3.1.4.jar
jbpm-identity-3.1.4.jar
jbpm-3.1.4.jar
部署hbm文件到項(xiàng)目
1 在jbpm文件夾中找到所有
的*.hbm.xml數(shù)據(jù)庫(kù)映射文件。放到項(xiàng)目的一個(gè)文件夾當(dāng)中。本例放到"com"gresoft"security"model"hbm文件夾中。并且在hibernate的sessionfactory建立時(shí),設(shè)置為相關(guān)路徑配置。
2 此文件需在spring管理的hibernate配置文件下修改,本例為
dataAccessContext-hibernate.xml,如下:
<!--Hibernate
SessionFatory-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle9Dialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
<property name="typeDefinitions">
<ref bean="jbpmTypes" />
</property>
<property name="mappingDirectoryLocations">
<list>
<value>
classpath*:/com/gresoft/security/model/hbm/
</value>
</list>
</property>
</bean>
設(shè)置大字段string-max
1 此文件需在spring管理的hibernate配置文件下修改,本例為
dataAccessContext-hibernate.xml,如下:
<!-- 處理大字
段 -->
<bean id="jbpmTypes" class="org.springframework.orm.hibernate3.TypeDefinitionBean">
<property name="typeName" value="string_max" />
<property name="typeClass" value="org.jbpm.db.hibernate.StringMax"
/>
</bean>
配置configration、template
說明:jbpmConfiguration是根據(jù)springmodules所
提供的
LocalJbpmConfigurationFactoryBean進(jìn)行配置,其集成好對(duì)jbpmConfiguration的管理。在系統(tǒng)使用時(shí)JbpmConfiguration需調(diào)用jbpmTemplate的jbpmTemplate.getJbpmConfiguration()方法得到。
1 此文件需在spring管理的hibernate配置文件下修改,本例為
dataAccessContext-hibernate.xml,如下:
<!-- jBPM
configuration-->
<bean id="jbpmConfiguration" class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">
<property
name="sessionFactory" ref="sessionFactory" />
<property
name="configuration" value="classpath:/datasql/jbpm.cfg.xml" />
</bean>
<!-- jBPM template -->
<bean id="jbpmTemplate" class="org.springmodules.workflow.jbpm31.JbpmTemplate">
<constructor-arg index="0" ref="jbpmConfiguration" />
</bean>
2 增加類路
徑中jbpm.cfg.xml文件,可以根據(jù)
jbpm-starters-kit-3.1.4"jbpm"src"java.jbpm"org"jbpm"default.jbpm.cfg.xml
復(fù)制后修改。本例放到/datasql/jbpm.cfg.xml下。上面配置文件有相關(guān)配置。全部?jī)?nèi)容如下:
<jbpm-configuration>
<!— - 增加如下內(nèi)容 - à
<jbpm-context>
<service
name="persistence">
<factory>
<bean
class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
<field name="isTransactionEnabled">
<false />
</field>
<field name="isCurrentSessionEnabled">
<true />
</field>
</bean>
</factory>
</service>
<service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory"
/>
<service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory"
/>
<service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory"
/>
<service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory"
/>
</jbpm-context>
<!-- configuration resource files pointing to
default configuration files in jbpm-{version}.jar -->
<!-- 不再使用<string name="resource.hibernate.cfg.xml" value="hibernate.cfg.xml" />-->
<string name="resource.business.calendar" value="org/jbpm/calendar/jbpm.business.calendar.properties"
/>
<string name="resource.default.modules" value="org/jbpm/graph/def/jbpm.default.modules.properties"
/>
<string name="resource.converter" value="org/jbpm/db/hibernate/jbpm.converter.properties"
/>
<string name="resource.action.types" value="org/jbpm/graph/action/action.types.xml" />
<string name="resource.node.types" value="org/jbpm/graph/node/node.types.xml" />
<string name="resource.parsers" value="org/jbpm/jpdl/par/jbpm.parsers.xml"
/>
<string name="resource.varmapping" value="org/jbpm/context/exe/jbpm.varmapping.xml" />
<long
name="jbpm.msg.wait.timout" value="5000" singleton="true" />
<int
name="jbpm.byte.block.size" value="1024" singleton="true" />
<string name="mail.smtp.host" value="localhost" />
<bean
name="jbpm.task.instance.factory"
class="org.jbpm.taskmgmt.impl.DefaultTaskInstanceFactoryImpl"
singleton="true" />
<bean
name="jbpm.variable.resolver"
class="org.jbpm.jpdl.el.impl.JbpmVariableResolver"
singleton="true" />
<bean
name="jbpm.mail.address.resolver"
class="org.jbpm.identity.mail.IdentityAddressResolver"
singleton="true" />
</jbpm-configuration>
過濾器的設(shè)置與建立
過濾器的建立是為了保證一個(gè)session的正常工
作。
1 web.xml中的修改
本例中描述如下:
<!-- 注入jbpm過濾器,使用統(tǒng)一的Session
-->
<filter>
<filter-name>JbpmContextFilter</filter-name>
<filter-class>com.gresoft.components.jbpm.JbpmContextHolder</filter-class>
</filter>
2建立對(duì)應(yīng)的類文件
本例中描述如下:
package
com.gresoft.components.jbpm;
import
java.io.IOException;
import
java.io.Serializable;
import
java.security.Principal;
import
javax.servlet.Filter;
import
javax.servlet.FilterChain;
import
javax.servlet.FilterConfig;
import
javax.servlet.ServletException;
import
javax.servlet.ServletRequest;
import
javax.servlet.ServletResponse;
import
javax.servlet.http.HttpServletRequest;
import
org.jbpm.JbpmConfiguration;
import
org.jbpm.JbpmContext;
import
org.springframework.web.context.WebApplicationContext;
public class
JbpmContextHolder implements Filter, Serializable {
private static final long serialVersionUID = 1L;
String jbpmConfigurationResource = null;
String jbpmContextName = null;
boolean isAuthenticationEnabled = true;
public void init(FilterConfig filterConfig) throws
ServletException {
// get the jbpm configuration resource
this.jbpmConfigurationResource = filterConfig
.getInitParameter("jbpm.configuration.resource");
// get the jbpm context to be used from the jbpm configuration
this.jbpmContextName = filterConfig
.getInitParameter("jbpm.context.name");
if (jbpmContextName == null) {
jbpmContextName = JbpmContext.DEFAULT_JBPM_CONTEXT_NAME;
}
// see if authentication is turned off
String isAuthenticationEnabledText = filterConfig
.getInitParameter("authentication");
if ((isAuthenticationEnabledText != null)
&&
("disabled".equalsIgnoreCase(isAuthenticationEnabledText))) {
isAuthenticationEnabled = false;
}
}
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
String actorId = null;
// see if we can get the authenticated swimlaneActorId
if (servletRequest instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest)
servletRequest;
Principal userPrincipal = httpServletRequest.getUserPrincipal();
if (userPrincipal != null) {
actorId = userPrincipal.getName();
}
}
JbpmContext jbpmContext = getJbpmConfiguration(servletRequest)
.createJbpmContext(jbpmContextName);
try {
if (isAuthenticationEnabled) {
jbpmContext.setActorId(actorId);
}
filterChain.doFilter(servletRequest, servletResponse);
} finally {
jbpmContext.close();
}
}
/*
* 從spring獲取JbpmConfiguration的bean加載方式
*/
protected JbpmConfiguration getJbpmConfiguration(
ServletRequest servletRequest) {
WebApplicationContext webApplicationContext =
(WebApplicationContext) ((HttpServletRequest) servletRequest)
.getSession()
.getServletContext()
.getAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
JbpmConfiguration jbpmConfiguration = (JbpmConfiguration)
webApplicationContext
.getBean("jbpmConfiguration");
// 得到業(yè)務(wù)Bean(在這里是你需要
注入的bean)
System.out.println("------------------------------------------------------------------------------------------");
System.out.println("jbpmconfiguration對(duì)象化=" + jbpmConfiguration.toString());
System.out.println("------------------------------------------------------------------------------------------");
return jbpmConfiguration;
}
public void destroy() {
}
}
編寫發(fā)布流程定義xml的人機(jī)頁面及程序
1 JSP頁面使用struts1.2,spring2.0,hibernate3.2框架。此為流程發(fā)布頁面。
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
</head>
<body>
<form action="項(xiàng)目名/jbpmtest.do?method=deploy"
name="formupload" method="post" enctype="multipart/form-data">
請(qǐng)選擇要發(fā)布的流程文件<input name="workflowfile"
type="file" id="workflowfile" >
<input type="submit"
name="submit">
</form>
</body>
</html>
2 后臺(tái)對(duì)應(yīng)類
/*******************************************************************************
* 文件名: JbpmAction.java<br>
* 版本: <br>
* 描述: <br>
* 版權(quán)所有: <br>
*
//////////////////////////////////////////////////////// <br>
* 創(chuàng)建者: 沙振中 <br>
* 創(chuàng)建日期: Dec 27, 2007 <br>
* 修改者: <br>
* 修改日期: <br>
* 修改說明: <br>
******************************************************************************/
package
com.gresoft.security.web;
import
java.io.InputStream;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.apache.commons.beanutils.DynaBean;
import
org.apache.commons.logging.Log;
import
org.apache.commons.logging.LogFactory;
import
org.apache.struts.action.ActionForm;
import
org.apache.struts.action.ActionForward;
import
org.apache.struts.action.ActionMapping;
import
org.apache.struts.upload.FormFile;
import
org.jbpm.JbpmContext;
import
org.jbpm.graph.def.ProcessDefinition;
import
org.springmodules.workflow.jbpm31.JbpmTemplate;
import
com.gresoft.commons.core.web.StrutsAction;
public class JbpmAction
extends StrutsAction {
private static Log log = LogFactory.getLog(JbpmAction.class);
private JbpmTemplate jbpmTemplate;
public void setjbpmTemplate(JbpmTemplate jbpmTemplate) {
this.jbpmTemplate = jbpmTemplate;
}
/**
* 進(jìn)入上傳流程主頁面
*
@param mapping
*
@param form
*
@param request
*
@param response
*
@return
*/
public
ActionForward index(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
return mapping.findForward("delpoyindex");
}
/**
* 上傳流程文件
*
@param mapping
*
@param form
*
@param request
*
@param response
*
@return
*/
public
ActionForward deploy(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)throws
Exception {
DynaBean dy = (DynaBean) form;
FormFile file = (FormFile) dy.get("workflowfile");
InputStream is =
file.getInputStream();
JbpmContext jbpmContext =
jbpmTemplate.getJbpmConfiguration().createJbpmContext();
ProcessDefinition processDefinition =
ProcessDefinition.parseXmlInputStream(is);
//利用容器的方法將流程定義數(shù)據(jù)部署到
數(shù)據(jù)庫(kù)上
jbpmContext.deployProcessDefinition(processDefinition);
//
關(guān)閉 jbpmContext
jbpmContext.close();
//
提交到數(shù)據(jù)庫(kù)當(dāng)中,使用統(tǒng)一的session
jbpmTemplate.getHibernateTemplate().flush();
log.info("流程部署成功!");
return mapping.findForward("delpoyindex");
}
}
注:相關(guān)ssh配置文件的設(shè)置需根
據(jù)自己實(shí)際項(xiàng)目為準(zhǔn)。
寫在最后
通過上述集成的工作,可以使你的項(xiàng)目中很好的集成jbpm。Jbpm流程的設(shè)置需根據(jù)實(shí)際業(yè)務(wù)相綁定。現(xiàn)在我們就可以在項(xiàng)目當(dāng)中應(yīng)用工作流了。