当公司领导指定使用struts2作为某项目的显示层实现技术时,而该项目使用了jbpm。
当使用jbpm时,正常情况下是要显示未知数量的业务表单页面。
一般情况下,在使用struts2(本人使用的情况下)的一般情况下,页面控制是已经写在struts的配置文件当中,也就是说要显示的页面基本是已知的了(未知页面,显然是无法配置的),因此一般情况下,当有新业务时,或者业务流程发生变化时(任务节点新增与删除等),就会导致业务表单页面的新增与删除,然后这种以xml配置方式,显然是无法满足需求的。
我们知道在使用springmvc时,viewname是可以在程序里指定,这样业务表单也是可以在程序里指定的,可以避免xml配置的不灵活性。显然struts2肯定也应该提供了这样的方式。
扩展以下两个类即可:
1、StrutsActionProxyFactory;
2、DefaultActionInvocation;
我们需要覆盖DefaultActionInvocation.createResult方法,
因为该方法的默认实现是从resultmappings里根据resultcode(action相关方法返回值)获取视图的,因此如果业务表单为在struts2的配置文件里进行配置,应该是会抛出异常。因此,我们只要覆盖该方法,并根据resultcode寻找视图(而不是从resultmapping里寻找)。一般情况,resultcode可以是业务表单页面的相对路径。
为了使用我们自己的ActionInvocation,就必须覆盖StrutsActionProxyFactory.createActionProxy方法,因为该方法已经指定返回StrutsActionProxy,我们覆盖StrutsActionProxyFactory.createActionProxy方法,返回我们自己的ActionInvocation。
具体实现如下:
public class IcomStrutsActionInvocation extends DefaultActionInvocation {
public static final String JBPM_PREFIX = "icom:";
public IcomStrutsActionInvocation(Map<String, Object> extraContext, boolean pushAction) {
super(extraContext, pushAction);
}
/**
*
*/
private static final long serialVersionUID = 1L;
public Result createResult() throws Exception {
if (resultCode != null && resultCode.startsWith(JBPM_PREFIX)) {// 如果是工作流表单(返回代码必须以icom:开头哦)
Map<String, String> resultParams = new HashMap<String, String>();
resultParams.put("location", resultCode.replace(JBPM_PREFIX, ""));
ResultConfig resultConfig = new ResultConfig.Builder(resultCode,
ServletDispatcherResult.class.getName()).addParams(resultParams)
.build();
return objectFactory.buildResult(resultConfig, invocationContext
.getContextMap());
} else {
return super.createResult();
}
}
}
public class IcomStrtuts2ActionFactory extends StrutsActionProxyFactory {
public ActionProxy createActionProxy(String namespace, String actionName,
String methodName, Map<String, Object> extraContext,
boolean executeResult, boolean cleanupContext) {
ActionInvocation inv = new IcomStrutsActionInvocation(extraContext, true);
container.inject(inv);
return super.createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
}
}
因为struts-default.xml文件是没有配置我们自己的实现类,因此需要在struts的配置文件添加我们自己的相关实现类,配置如下:
<struts>
<bean class="com.icom.tech.struts2.IcomStrtuts2ActionFactory"
name="default" type="com.opensymphony.xwork2.ActionProxyFactory" />
...
</struts>
struts-action返回resultcode例子:
public String forTask() throws Exception {
TaskService taskService = processEngine.getTaskService();
task = taskService.getTask(taskId);
if (null == task)
throw new NullPointerException("id为:" + taskId + " 的任务已经被处理...");
taskService.getVariableNames(taskId);
Map<String, Object> variables = taskService.getVariables(taskId,
taskService.getVariableNames(taskId));
if (!(null == variables || variables.isEmpty())) {
ValueStack stack = ActionContext.getContext().getValueStack();
Iterator<String> it = variables.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
logger.info("将要压入的参数:" + key + " 值为:" + variables.get(key));
Object value = variables.get(key);
stack.set(key, value);
}
}
if(flag){
// 获取表单页面路径信息
return IcomStrutsActionInvocation.JBPM_PREFIX+retriveFormResource();
}
return IcomStrutsActionInvocation.JBPM_PREFIX
+ task.getFormResourceName();
}
private String retriveFormResource() throws Exception {
String formResourceName = task.getFormResourceName();
String excutionId = task.getExecutionId();
Execution e = processEngine.getExecutionService().findExecutionById(
excutionId);
ProcessDefinition pd = processEngine.getRepositoryService()
.createProcessDefinitionQuery().processDefinitionId(
e.getProcessDefinitionId()).uniqueResult();
DeploymentImpl deployment = (DeploymentImpl) processEngine
.getRepositoryService().createDeploymentQuery().deploymentId(
pd.getDeploymentId()).uniqueResult();
String path = deployment.getId() + "/" + pd.getId() + "/"
+ formResourceName;
File formFile = new File(formBaseDir, path);
// 首先判断文件是否存在,不存在则创建表单文件
if (!formFile.exists())
synchronized (processEngine) {
if(!formFile.getParentFile().exists()){
formFile.getParentFile().mkdirs();
}
byte[] buf = deployment.getBytes(formResourceName);
// 写入特定存放目录中
FileOutputStream fos = new FileOutputStream(formFile);
fos.write(buf);
fos.close();
}
return DEFAULT_FORM_BASE_DIR + path;
}
以下是jpdl编写的流程定义文件片段:
<task assignee="${user}" name="材料补正" form="printSupplyMaterial.jsp">
<on event="start">
<event-listener factory="businessInstanceListener" method="getInstance" />
</on>
<on event="timeout">
<timer duedate="${tc_supplyMaterial_timeout}" />
<event-listener class="com.icom.cpb.workflow.listener.ChangeColorListener" auto-wire="true" >
<property name="fontColor">
<string value="${tc_supplyMaterial_timeout_color}"/>
</property>
<property name="businessInstanceService">
<ref object="businessInstanceService"/>
</property>
</event-listener>
</on>
<transition name="未补全" to="不受理" >
<event-listener class="com.icom.cpb.workflow.listener.IncreaseDocNumberListner" >
<property name="userInfoService">
<ref object="userInfoService" />
</property>
<property name="docNumberService">
<ref object="docNumberService" />
</property>
<property name="docnumberName">
<string value="不予受理" />
</property>
<property name="variableName">
<string value="recode" />
</property>
</event-listener>
<event-listener class="com.icom.cpb.workflow.listener.ResetCreateTimeListener">
<property name="businessInstanceService">
<ref object="businessInstanceService"/>
</property>
</event-listener>
</transition>
<!--
<transition name="已补全" to="受理" >
<event-listener class="com.icom.cpb.workflow.listener.IncreaseDocNumberListner" >
<property name="userInfoService">
<ref object="userInfoService" />
</property>
<property name="docNumberService">
<ref object="docNumberService" />
</property>
<property name="docnumberName">
<string value="受理" />
</property>
<property name="variableName">
<string value="accode" />
</property>
</event-listener>
</transition>
-->
<transition name="已补全" to="受理" >
<event-listener class="com.icom.cpb.workflow.listener.ClearMaterialsListener" >
<property name="businessInstanceService">
<ref object="businessInstanceService"/>
</property>
<property name="receivedDocInfoService">
<ref object="receivedDocInfoService"/>
</property>
</event-listener>
<event-listener class="com.icom.cpb.workflow.listener.ResetCreateTimeListener">
<property name="businessInstanceService">
<ref object="businessInstanceService"/>
</property>
</event-listener>
<event-listener class="com.icom.cpb.workflow.listener.IncreaseDocNumberListner" >
<property name="userInfoService">
<ref object="userInfoService" />
</property>
<property name="docNumberService">
<ref object="docNumberService" />
</property>
<property name="docnumberName">
<string value="受理" />
</property>
<property name="variableName">
<string value="accode" />
</property>
</event-listener>
</transition>
</task>
分享到:
相关推荐
《Spring、Struts2与JBPM 3.2的整合应用详解》 在现代企业级应用开发中,Spring、Struts2和JBPM是三个重要的技术框架。Spring以其强大的依赖注入(DI)和面向切面编程(AOP)功能,为应用程序提供了灵活的基础架构...
3. **jbpm4与Struts2的整合** - **前端控制器**:Struts2作为MVC框架的前端控制器,处理HTTP请求并分发到相应的业务逻辑。jbpm4的流程启动、结束等操作可以通过Struts2的Action类进行封装,提供Web界面操作。 - **...
在这个"ssh-jbpm.rar"压缩包中,我们关注的是Struts2的应用实例,它可能包含了与jbpm(Job Business Process Management,工作流管理系统)集成的内容,以及SSH(Spring、Struts2和Hibernate)这一经典Java EE开发栈...
在这个场景中,我们讨论的是如何将Spring 2.5.4、Hibernate 3.2.6、Struts2以及jbpm 3.2.2这四个组件集成到一个项目中。下面将分别介绍这些组件以及它们在整合过程中的配置细节。 1. **Spring 2.5.4**: Spring 是...
**jbpm4整合struts2+spring2.5+hibernate3.3** 是一个经典的Java企业级应用集成框架,用于构建业务流程管理系统。jbpm4是Business Process Management(业务流程管理)的一个开源框架,它允许开发者设计、执行、监控...
jbpm4与Struts2的结合是一个常见的企业级应用架构,用于实现业务流程管理和用户界面交互。jbpm4是一个强大的工作流和业务流程管理框架,它允许开发者定义、执行和监控复杂的业务流程。而Struts2则是一个流行的MVC...
- **jbpm集成**:在Spring配置文件中配置jbpm的SessionFactory和TaskService,以便于调用流程服务进行流程实例的启动、完成等操作。 这个配置方法是多年前的标准实践,现代应用可能已经采用更新的版本,如Spring ...
SSH2与Jbpm的集成是企业级应用中常见的技术结合,主要应用于流程管理与权限控制。SSH2指的是Spring、Struts2和Hibernate这三个开源框架的组合,它们分别是Java Web开发中的依赖注入容器、MVC框架和持久层框架。而...
在进行Struts与jbpm的整合时,我们需要关注以下几个关键知识点: 1. **jbpm框架**:jbpm是一个开源的工作流管理系统,它提供了一套完整的工作流定义语言(jPDL),用于描述流程实例的生命周期。jbpm支持BPMN 2.0...
**JBPM4与SSH整合详解** 在企业级应用开发中,Spring(Struts2、Hibernate)集成,简称SSH,是常见的Java Web开发框架组合。它们分别负责控制层、视图层和持久层的处理,而JBPM4则是一个强大的工作流管理系统,用于...
这个"jBPM4完整例子"是一个基于SSH(Struts2、Spring、Hibernate)框架集成jBPM4.4的请假流程应用,非常适合初学者了解如何在实际项目中运用jBPM4进行工作流开发。 首先,我们来详细了解一下SSH框架。SSH是Java Web...
SSH集成JBPM4是一个关于将Spring、Struts2和Hibernate(SSH)这三大Java Web开发框架与Business Process Management System(BPM,业务流程管理系统)JBPM4整合的项目实例。SSH是Java领域常用的轻量级MVC框架组合,...
在本资源中,我们主要关注的是使用Eclipse集成开发环境(IDE)进行Web应用程序的开发,特别是集成Struts、Hibernate、Spring和JBPM这四个关键的技术框架。这四个框架是Java企业级应用开发中的核心组件,它们分别负责...
综上所述,jbPM4与SSH的集成为企业提供了强大的业务流程管理能力,结合了SSH的灵活性和jbPM4的工作流优势。开发者可以通过这种集成实现复杂的业务逻辑,提高系统的可维护性和扩展性。在实际项目中,理解并熟练掌握这...
【jbpm4 s2sh 请假流程】是一个基于jbpm工作流引擎和SSH(Struts2、Spring、Hibernate)框架的简单示例应用,用于演示如何在Java Web环境中实现一个请假流程。在这个教程中,我们将深入理解jbpm4的工作原理以及如何...
开发者可以通过研究这些文件,了解如何将Struts2、Spring、Hibernate和Jbpm集成起来,实现一个完整的公文审批流程。这个实例不仅可以帮助学习者理解这些技术的用法,还可以作为模板,用于构建其他类型的工作流应用,...
以上JAR文件的集合构成了一个基本的jbpm4开发环境,它们共同支持了工作流的定义、执行、监控和管理,以及与业务规则、数据库、Web应用的集成。开发者在学习和实践中,需要理解和掌握这些组件的用途和相互作用,以便...
标题中的"spring+struts1+hibernate+jbpm实例"揭示了这是一个基于Java技术栈的Web应用程序开发实例,其中涉及四大核心技术:Spring、Struts1、Hibernate和JBPM。接下来,我们将深入探讨这些技术及其在实际项目中的...
jbPM5和SSH(Spring、Struts、Hibernate)的集成是企业级Java应用开发中的常见实践,旨在利用jbPM5的流程管理能力与SSH框架的强大功能,构建出高效、灵活的企业级业务系统。jbPM5是一个开源的工作流和业务流程管理...