工作流Activiti的学习小结(八)Activiti自动执行的应用
工作流Activiti的学习总结(八)Activiti自动执行的应用
工作流activiti自动执行任务的开发应用
工作流模拟某公司请假流程情景如下:
1.开发人员请假流程,如果开发人员请假,如果请假天数小于3天,组长批准,人事批准即可请假。
2.如果请假大约三天,需要项目经理或者产品经理批准,并且项目总监批准
模拟自动审批:
只需要启动一个流程实例,它会自动执行到结束。这种情况下,你不需要关注流
程的执行进度,而只需要把精力集中在每个结点的处理逻辑(通常是简单或者复杂的商业逻辑)上。
流程设计图如下:
流程配置文件AutoExecuteTask.bpmn20.xml如下:
<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"> <process id="AutoExecuteTask" name="AutoExecuteTask"> <startEvent id="startevent1" name="Start"></startEvent> <parallelGateway id="parallelgateway1" name="多种请假方式"></parallelGateway> <serviceTask id="servicetask1" name="项目经理同意" activiti:class="com.easyway.workflow.activiti.gateway.DeveloperManagerServiceTask"></serviceTask> <serviceTask id="servicetask2" name="产品经理同意" activiti:class="com.easyway.workflow.activiti.gateway.ProductManagerServiceTask"></serviceTask> <serviceTask id="servicetask3" name="项目组长同意" activiti:class="com.easyway.workflow.activiti.gateway.TeamLeaderServiceTask"></serviceTask> <parallelGateway id="parallelgateway2" name="First Join"></parallelGateway> <serviceTask id="servicetask4" name="项目总监同意" activiti:class="com.easyway.workflow.activiti.gateway.ProductBossServiceTask"></serviceTask> <parallelGateway id="parallelgateway3" name="人事判断"></parallelGateway> <serviceTask id="servicetask5" name="人事部门同意" activiti:class="com.easyway.workflow.activiti.gateway.HumanResouceServiceTask"></serviceTask> <endEvent id="endevent1" name="End"></endEvent> <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="parallelgateway1"></sequenceFlow> <sequenceFlow id="flow2" name="" sourceRef="parallelgateway1" targetRef="servicetask1"></sequenceFlow> <sequenceFlow id="flow3" name="" sourceRef="parallelgateway1" targetRef="servicetask2"></sequenceFlow> <sequenceFlow id="flow4" name="" sourceRef="parallelgateway1" targetRef="servicetask3"></sequenceFlow> <sequenceFlow id="flow5" name="" sourceRef="servicetask1" targetRef="parallelgateway2"></sequenceFlow> <sequenceFlow id="flow6" name="" sourceRef="servicetask2" targetRef="parallelgateway2"></sequenceFlow> <sequenceFlow id="flow7" name="" sourceRef="servicetask3" targetRef="parallelgateway3"></sequenceFlow> <sequenceFlow id="flow8" name="" sourceRef="parallelgateway2" targetRef="servicetask4"></sequenceFlow> <sequenceFlow id="flow9" name="" sourceRef="servicetask4" targetRef="parallelgateway3"></sequenceFlow> <sequenceFlow id="flow10" name="" sourceRef="parallelgateway3" targetRef="servicetask5"></sequenceFlow> <sequenceFlow id="flow11" name="" sourceRef="servicetask5" targetRef="endevent1"></sequenceFlow> </process> </definitions>
package com.easyway.workflow.activiti.gateway; import java.util.logging.Logger; /** * execute方法的参数DelegateExecution execution可以在流程中各个结点之间传递流程变量。 *通过基于Activiti 5.6的<parallelGateway>、<serviceTask>、<receiveTask>、<userTask>元素。 * *自动执行 <serviceTask>元素,可以实现自动活动,语法如下所示: <serviceTask id="serviceTaskId" name="serviceTaskName" activiti:class="org.shirdrn.workflow.activiti.gateway.ServiceTaskClass"/> 其中,activiti:class属性为该结点对应的处理类,该类要求实现org.activiti.engine.delegate.JavaDelegate接口 * * <serviceTask id="servicetask1" name="项目经理同意" activiti:class="com.easyway.workflow.activiti.gateway.DeveloperManagerServiceTask"></serviceTask> * 项目经理审批过程 * @author longgangbai * * * 2011-12-17 下午07:45:47 */ public class DeveloperManagerServiceTask implements JavaDelegate { private final Logger log = Logger.getLogger(DeveloperManagerServiceTask.class.getName()); @Override public void execute(DelegateExecution execution) throws Exception { Thread.sleep(10000); log.info("variavles=" + execution.getVariables()); execution.setVariable("项目经理", "请假天数大约3天,同意请假。"); log.info("项目经理,请假天数大约3天,同意请假。."); } }
package com.easyway.workflow.activiti.gateway; import java.util.logging.Logger; /** * execute方法的参数DelegateExecution execution可以在流程中各个结点之间传递流程变量。 * * * <serviceTask id="servicetask2" name="产品经理同意" activiti:class="com.easyway.workflow.activiti.gateway.ProductManagerServiceTask"></serviceTask> * 产品经理审批过程 * @author longgangbai * * 2011-12-17 下午07:45:47 */ public class ProductManagerServiceTask implements JavaDelegate { private final Logger log = Logger.getLogger(ProductManagerServiceTask.class.getName()); @Override public void execute(DelegateExecution execution) throws Exception { Thread.sleep(10000); log.info("variavles=" + execution.getVariables()); execution.setVariable("产品经理", "请假天数大约3天,同意请假。"); log.info("产品经理,请假天数大约3天,同意请假。"); } }
package com.easyway.workflow.activiti.gateway; import java.util.logging.Logger; /** * 项目组长批准请假 * 模拟当开发人员请假小于3天,组长比准 * * * <serviceTask id="servicetask3" name="项目组长同意" activiti:class="com.easyway.workflow.activiti.gateway.TeamLeaderServiceTask"></serviceTask> * @author longgangbai * * 2011-12-17 上午09:07:37 */ public class TeamLeaderServiceTask implements JavaDelegate { private final Logger log = Logger.getLogger(TeamLeaderServiceTask.class.getName()); @Override public void execute(DelegateExecution execution) throws Exception { Thread.sleep(10000); log.info("variavles=" + execution.getVariables()); execution.setVariable("项目组长", "请假天数小于3天,同意请假。"); log.info("项目组长,请假天数小于3天,同意请假。"); } }
package com.easyway.workflow.activiti.gateway; import java.util.logging.Logger; /** * execute方法的参数DelegateExecution execution可以在流程中各个结点之间传递流程变量。 * * <serviceTask id="servicetask4" name="项目总监同意" activiti:class="com.easyway.workflow.activiti.gateway.ProductBossServiceTask"></serviceTask> * * 项目总监审批过程 * @author longgangbai * * 2011-12-17 下午07:45:47 */ public class ProductBossServiceTask implements JavaDelegate { private final Logger log = Logger.getLogger(ProductBossServiceTask.class.getName()); @Override public void execute(DelegateExecution execution) throws Exception { Thread.sleep(10000); log.info("variavles=" + execution.getVariables()); execution.setVariable("项目总监", "请假天数大约3天,同意请假。"); log.info("项目总监,请假天数大约3天,同意请假。"); } }
package com.easyway.workflow.activiti.gateway; import java.util.logging.Logger; /** * execute方法的参数DelegateExecution execution可以在流程中各个结点之间传递流程变量。 *自动执行 <serviceTask>元素,可以实现自动活动,语法如下所示: <serviceTask id="serviceTaskId" name="serviceTaskName" activiti:class="org.shirdrn.workflow.activiti.gateway.ServiceTaskClass"/> 其中,activiti:class属性为该结点对应的处理类,该类要求实现org.activiti.engine.delegate.JavaDelegate接口 * <serviceTask id="servicetask5" name="人事部门同意" activiti:class="com.easyway.workflow.activiti.gateway.HumanResouceServiceTask"></serviceTask> * * 人事部门审批过程 * @author longgangbai * * 2011-12-17 下午07:45:47 */ public class HumanResouceServiceTask implements JavaDelegate { private final Logger log = Logger.getLogger(HumanResouceServiceTask.class.getName()); @Override public void execute(DelegateExecution execution) throws Exception { Thread.sleep(10000); log.info("variavles=" + execution.getVariables()); execution.setVariable("人事部门", "请假天数大约3天,同意请假。"); log.info("人事部门 ,请假天数大约3天,同意请假。"); } }
package com.easyway.workflow.activiti.gateway; import junit.framework.TestCase; import org.activiti.engine.FormService; import org.activiti.engine.HistoryService; import org.activiti.engine.IdentityService; import org.activiti.engine.ManagementService; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngines; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; import org.activiti.engine.test.ActivitiTestCase; /** * 主要是在测试之前做一些初始化工作,主要包括流程引擎实例 * 的构建,及其流程提供的基本服务。 * 目的:让开发者熟悉工作流使用过程使用的几个步骤 * 1.加载相关的工作流全局配置文件activiti.cfg.xml配置文件信息 * 2.获取工作流相关的服务(RepositoryService,RuntimeService, * TaskService,HistoryService,FormService,ManagementService, * IdentityService等) * 2.加载工作流文件*.bpmn20.xml信息 * * 3.部署工作流 * 部署工作流由多种方式,在以后会相继讲解 * * @author longgangbai * * 2011-12-17 下午07:48:59 */ public abstract class AbstractTest extends TestCase { private ProcessEngine processEngine; protected String deploymentId; protected RepositoryService repositoryService; protected RuntimeService runtimeService; protected TaskService taskService; protected FormService formService; protected HistoryService historyService; protected IdentityService identityService; protected ManagementService managementService; /** * 测试用例开始初始化工作 * 1.创建相关的工作流程对象ProcessEngine * 2.创建相关的服务 * 3. */ @Override protected void setUp() throws Exception { super.setUp(); //由于ProcessEngine为线程安全性对象,整个项目可以共用一个 if(processEngine==null) { //此处使用此种方法调用的activiti的配置文件为 classpath路径下的activiti.cfg.xml //采用的H2的数据库 processEngine = ProcessEngines.getDefaultProcessEngine(); } //获取工作流的各种服务信息 repositoryService = processEngine.getRepositoryService(); runtimeService = processEngine.getRuntimeService(); taskService = processEngine.getTaskService(); formService = processEngine.getFormService(); historyService = processEngine.getHistoryService(); identityService = processEngine.getIdentityService(); managementService = processEngine.getManagementService(); //调用扩展的初始化工作 initialize(); } /** * test销毁方法 */ @Override protected void tearDown() throws Exception { super.tearDown(); destroy(); } /** * 便于子类的工作的初始化的扩展工作 * * * @throws Exception */ protected abstract void initialize() throws Exception; /** * 便于子类的工作的销毁的扩展工作 * * @throws Exception */ protected abstract void destroy() throws Exception; }
package com.easyway.workflow.activiti.gateway; import org.activiti.engine.runtime.ProcessInstance; /** * Activiti 5.6支持流程活动自动执行与手工触发执行。 * 其中,自动执行是指,在启动流程之前,准备流程所需要的控制流程进度的变量数据, * 启动流程之后,无需外部干预,就能够按照预定义的流程执行; * 过基于Activiti 5.6的<parallelGateway>、<serviceTask>、<receiveTask>、<userTask>元素 * * * 自动执行 *<serviceTask>元素,可以实现自动活动,语法如下所示: *<serviceTask id="serviceTaskId" name="serviceTaskName" *activiti:class="org.shirdrn.workflow.activiti.gateway.ServiceTaskClass"/> * * 其中,activiti:class属性为该结点对应的处理类,该类要求实现org.activiti.engine.delegate.JavaDelegate * 接口,该接口定义如下所示: * * <pre> * package org.activiti.engine.delegate; * public interface JavaDelegate { * void execute(DelegateExecution execution) throws Exception; * } * </pre> * execute方法的参数DelegateExecution execution可以在流程中各个结点之间传递流程变量 * * 工作流模拟某公司请假流程情景如下: * 1.开发人员请假流程,如果开发人员请假,如果请假天数小于3天,组长批准,人事批准即可请假。 * 2.如果请假大约三天,需要项目经理或者产品经理批准,并且项目总监批准 * * 模拟自动审批:只需要启动一个流程实例,它会自动执行到结束。这种情况下,你不需要关注流 * 程的执行进度,而只需要把精力集中在每个结点的处理逻辑(通常是简单或者复杂的商业逻辑)上。 * * * * @author longgangbai * * 2011-12-17 08:01:55 */ public class AutomaticParallelGatewayTest extends AbstractTest { private String deploymentId; @Override protected void initialize() throws Exception { deploymentId = repositoryService.createDeployment() .addClasspathResource("diagrams/AutoExecuteTask.bpmn20.xml") .deploy().getId(); } @Override protected void destroy() throws Exception { repositoryService.deleteDeployment(deploymentId, true); } /** * 使用注解部署 工作流程 */ @Deployment public void testForkJoin() { //根据流程ID获取流程实例 ProcessInstance pi = runtimeService.startProcessInstanceByKey("AutoExecuteTask"); //根据运行是服务检查是否执行的结束 assertEquals(true, pi.isEnded()); } }
运行结果如下(运行单元测试之前必须启动H2数据库,否则报错):
2011-12-18 12:50:13 org.activiti.engine.ProcessEngines initProcessEnginFromResource 信息: initializing process engine for resource jar:file:/C:/activiti-rest/activiti-cfg.jar!/activiti.cfg.xml 2011-12-18 12:50:17 org.activiti.engine.impl.ProcessEngineImpl <init> 信息: ProcessEngine default created 2011-12-18 12:50:17 org.activiti.engine.ProcessEngines initProcessEnginFromResource 信息: initialised process engine default 2011-12-18 12:50:17 org.activiti.engine.impl.jobexecutor.JobAcquisitionThread run 信息: JobAcquisitionThread starting to acquire jobs 2011-12-18 12:50:17 org.activiti.engine.impl.bpmn.deployer.BpmnDeployer deploy 信息: Processing resource diagrams/AutoExecuteTask.bpmn20.xml 2011-12-18 12:50:17 org.activiti.engine.impl.bpmn.parser.BpmnParse parseDefinitionsAttributes 信息: XMLSchema currently not supported as typeLanguage 2011-12-18 12:50:17 org.activiti.engine.impl.bpmn.parser.BpmnParse parseDefinitionsAttributes 信息: XPath currently not supported as expressionLanguage 2011-12-18 12:50:27 com.easyway.workflow.activiti.gateway.DeveloperManagerServiceTask execute 信息: variavles={} 2011-12-18 12:50:27 com.easyway.workflow.activiti.gateway.DeveloperManagerServiceTask execute 信息: 项目经理,请假天数大约3天,同意请假。. 2011-12-18 12:50:37 com.easyway.workflow.activiti.gateway.ProductManagerServiceTask execute 信息: variavles={项目经理=请假天数大约3天,同意请假。} 2011-12-18 12:50:37 com.easyway.workflow.activiti.gateway.ProductManagerServiceTask execute 信息: 产品经理,请假天数大约3天,同意请假。 2011-12-18 12:50:47 com.easyway.workflow.activiti.gateway.ProductBossServiceTask execute 信息: variavles={项目经理=请假天数大约3天,同意请假。, 产品经理=请假天数大约3天,同意请假。} 2011-12-18 12:50:47 com.easyway.workflow.activiti.gateway.ProductBossServiceTask execute 信息: 项目总监,请假天数大约3天,同意请假。 2011-12-18 12:50:57 com.easyway.workflow.activiti.gateway.TeamLeaderServiceTask execute 信息: variavles={项目总监=请假天数大约3天,同意请假。, 项目经理=请假天数大约3天,同意请假。, 产品经理=请假天数大约3天,同意请假。} 2011-12-18 12:50:57 com.easyway.workflow.activiti.gateway.TeamLeaderServiceTask execute 信息: 项目组长,请假天数小于3天,同意请假。 2011-12-18 12:51:08 com.easyway.workflow.activiti.gateway.HumanResouceServiceTask execute 信息: variavles={项目总监=请假天数大约3天,同意请假。, 项目组长=请假天数小于3天,同意请假。, 项目经理=请假天数大约3天,同意请假。, 产品经理=请假天数大约3天,同意请假。} 2011-12-18 12:51:08 com.easyway.workflow.activiti.gateway.HumanResouceServiceTask execute 信息: 人事部门 ,请假天数大约3天,同意请假。
由上面运行结果可以看出:
1.XPath currently not supported as expressionLanguage:原因工作流activiti表达式UEL必须在JDK1.5+以上,其实是UEL在JDK1.6中提供,本人采用JDK1.5.
2.:/C:/activiti-rest/activiti-cfg.jar!/activiti.cfg.xml:全局activiti配置文件采用默认的配置文件。
1 楼
dashamo
2012-06-04
你好,请教你一个问题,我是刚学activiti的
activiti下载包里有一个工程activiti-engine-examples
我拿 VacationRequest.bpmn20.xml 这个请假流程作为一个学习例子。假期申请人A提交一个开始节点的表单(request.form)时没有问题,这时启动一个流程实例,并给相关人员B生成一个代理任务,这也没问题,但当相应人员B处理该代理任务也就是处理A的请假请求时,他提交他的任务表单approve.form ,后台代码如下
String taskId = request.getParameter("taskId");
String vacationApproved = request.getParameter("vacationApproved");
String managerMotivation = request.getParameter("managerMotivation");
Map<String, String> formProperties = new HashMap<String, String>();
formProperties.put("vacationApproved_type", vacationApproved_type);
formProperties.put("vacationApproved", vacationApproved);
formProperties.put("managerMotivation", managerMotivation);
formService.submitTaskFormData(taskId, formProperties);
这时最后一句话 formService.submitTaskFormData(taskId, formProperties);报错误,错误如下:
严重: Error while closing command context
org.activiti.engine.ActivitiException: condition expression returns non-Boolean: true (java.lang.String)
at org.activiti.engine.impl.el.UelExpressionCondition.evaluate(UelExpressionCondition.java:43)
at org.activiti.engine.impl.bpmn.behavior.ExclusiveGatewayActivityBehavior.leave(ExclusiveGatewayActivityBehavior.java:63)
at org.activiti.engine.impl.bpmn.behavior.FlowNodeActivityBehavior.execute(FlowNodeActivityBehavior.java:36)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute.execute(AtomicOperationActivityExecute.java:44)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:76)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:497)
意思是表达式返回的不是布尔值,确实不是布尔值,
在 approve.form 中vacationApproved确实要求是boolean类型的
<select name="vacationApproved">
<option value="true">Yes</option>
<option value="false">No</option>
</select>
<input type="hidden" name="vacationApproved_type" value="Boolean" />
我传递到后台的
String vacationApproved = request.getParameter("vacationApproved");
vacationApproved 是字符串 “true”,
可是流程文件中审批请假的这个用户任务后的这个分支节点的输入条件要求的表达式是
${vacationApproved}
流程文件片段如下
<sequenceFlow id="flow3" sourceRef="requestApprovedDecision" targetRef="sendApprovalMail">
<conditionExpression xsi:type="tFormalExpression">${vacationApproved}</conditionExpression>
</sequenceFlow>
看意思是要求vacationApproved是布尔类型的,可这个变量
是请假审批人提交表单的一个数据,这个数据只能是字符串型的,因为
formService 这个服务类提交用户任务表单的方法是
void submitTaskFormData(String taskId, Map<String, String>
properties);
只能传递字符串。
现在的问题就是我传递字符串过去后台报错说 返回值是字符串“true”,不是boolean 类型的,可是我也不能直接传递一个boolean 类型的过去呀,因为api 不允许。
怎么办?
请教了!
activiti下载包里有一个工程activiti-engine-examples
我拿 VacationRequest.bpmn20.xml 这个请假流程作为一个学习例子。假期申请人A提交一个开始节点的表单(request.form)时没有问题,这时启动一个流程实例,并给相关人员B生成一个代理任务,这也没问题,但当相应人员B处理该代理任务也就是处理A的请假请求时,他提交他的任务表单approve.form ,后台代码如下
String taskId = request.getParameter("taskId");
String vacationApproved = request.getParameter("vacationApproved");
String managerMotivation = request.getParameter("managerMotivation");
Map<String, String> formProperties = new HashMap<String, String>();
formProperties.put("vacationApproved_type", vacationApproved_type);
formProperties.put("vacationApproved", vacationApproved);
formProperties.put("managerMotivation", managerMotivation);
formService.submitTaskFormData(taskId, formProperties);
这时最后一句话 formService.submitTaskFormData(taskId, formProperties);报错误,错误如下:
严重: Error while closing command context
org.activiti.engine.ActivitiException: condition expression returns non-Boolean: true (java.lang.String)
at org.activiti.engine.impl.el.UelExpressionCondition.evaluate(UelExpressionCondition.java:43)
at org.activiti.engine.impl.bpmn.behavior.ExclusiveGatewayActivityBehavior.leave(ExclusiveGatewayActivityBehavior.java:63)
at org.activiti.engine.impl.bpmn.behavior.FlowNodeActivityBehavior.execute(FlowNodeActivityBehavior.java:36)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute.execute(AtomicOperationActivityExecute.java:44)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:76)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:497)
意思是表达式返回的不是布尔值,确实不是布尔值,
在 approve.form 中vacationApproved确实要求是boolean类型的
<select name="vacationApproved">
<option value="true">Yes</option>
<option value="false">No</option>
</select>
<input type="hidden" name="vacationApproved_type" value="Boolean" />
我传递到后台的
String vacationApproved = request.getParameter("vacationApproved");
vacationApproved 是字符串 “true”,
可是流程文件中审批请假的这个用户任务后的这个分支节点的输入条件要求的表达式是
${vacationApproved}
流程文件片段如下
<sequenceFlow id="flow3" sourceRef="requestApprovedDecision" targetRef="sendApprovalMail">
<conditionExpression xsi:type="tFormalExpression">${vacationApproved}</conditionExpression>
</sequenceFlow>
看意思是要求vacationApproved是布尔类型的,可这个变量
是请假审批人提交表单的一个数据,这个数据只能是字符串型的,因为
formService 这个服务类提交用户任务表单的方法是
void submitTaskFormData(String taskId, Map<String, String>
properties);
只能传递字符串。
现在的问题就是我传递字符串过去后台报错说 返回值是字符串“true”,不是boolean 类型的,可是我也不能直接传递一个boolean 类型的过去呀,因为api 不允许。
怎么办?
请教了!
2 楼
longgangbai
2012-06-06
“true”,
你页面下拉框获取的"true"为字符串需要你转换为boolean值,明白吗?
dashamo 写道
你好,请教你一个问题,我是刚学activiti的
activiti下载包里有一个工程activiti-engine-examples
我拿 VacationRequest.bpmn20.xml 这个请假流程作为一个学习例子。假期申请人A提交一个开始节点的表单(request.form)时没有问题,这时启动一个流程实例,并给相关人员B生成一个代理任务,这也没问题,但当相应人员B处理该代理任务也就是处理A的请假请求时,他提交他的任务表单approve.form ,后台代码如下
String taskId = request.getParameter("taskId");
String vacationApproved = request.getParameter("vacationApproved");
String managerMotivation = request.getParameter("managerMotivation");
Map<String, String> formProperties = new HashMap<String, String>();
formProperties.put("vacationApproved_type", vacationApproved_type);
formProperties.put("vacationApproved", vacationApproved);
formProperties.put("managerMotivation", managerMotivation);
formService.submitTaskFormData(taskId, formProperties);
这时最后一句话 formService.submitTaskFormData(taskId, formProperties);报错误,错误如下:
严重: Error while closing command context
org.activiti.engine.ActivitiException: condition expression returns non-Boolean: true (java.lang.String)
at org.activiti.engine.impl.el.UelExpressionCondition.evaluate(UelExpressionCondition.java:43)
at org.activiti.engine.impl.bpmn.behavior.ExclusiveGatewayActivityBehavior.leave(ExclusiveGatewayActivityBehavior.java:63)
at org.activiti.engine.impl.bpmn.behavior.FlowNodeActivityBehavior.execute(FlowNodeActivityBehavior.java:36)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute.execute(AtomicOperationActivityExecute.java:44)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:76)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:497)
意思是表达式返回的不是布尔值,确实不是布尔值,
在 approve.form 中vacationApproved确实要求是boolean类型的
<select name="vacationApproved">
<option value="true">Yes</option>
<option value="false">No</option>
</select>
<input type="hidden" name="vacationApproved_type" value="Boolean" />
我传递到后台的
String vacationApproved = request.getParameter("vacationApproved");
vacationApproved 是字符串 “true”,
可是流程文件中审批请假的这个用户任务后的这个分支节点的输入条件要求的表达式是
${vacationApproved}
流程文件片段如下
<sequenceFlow id="flow3" sourceRef="requestApprovedDecision" targetRef="sendApprovalMail">
<conditionExpression xsi:type="tFormalExpression">${vacationApproved}</conditionExpression>
</sequenceFlow>
看意思是要求vacationApproved是布尔类型的,可这个变量
是请假审批人提交表单的一个数据,这个数据只能是字符串型的,因为
formService 这个服务类提交用户任务表单的方法是
void submitTaskFormData(String taskId, Map<String, String>
properties);
只能传递字符串。
现在的问题就是我传递字符串过去后台报错说 返回值是字符串“true”,不是boolean 类型的,可是我也不能直接传递一个boolean 类型的过去呀,因为api 不允许。
怎么办?
请教了!
activiti下载包里有一个工程activiti-engine-examples
我拿 VacationRequest.bpmn20.xml 这个请假流程作为一个学习例子。假期申请人A提交一个开始节点的表单(request.form)时没有问题,这时启动一个流程实例,并给相关人员B生成一个代理任务,这也没问题,但当相应人员B处理该代理任务也就是处理A的请假请求时,他提交他的任务表单approve.form ,后台代码如下
String taskId = request.getParameter("taskId");
String vacationApproved = request.getParameter("vacationApproved");
String managerMotivation = request.getParameter("managerMotivation");
Map<String, String> formProperties = new HashMap<String, String>();
formProperties.put("vacationApproved_type", vacationApproved_type);
formProperties.put("vacationApproved", vacationApproved);
formProperties.put("managerMotivation", managerMotivation);
formService.submitTaskFormData(taskId, formProperties);
这时最后一句话 formService.submitTaskFormData(taskId, formProperties);报错误,错误如下:
严重: Error while closing command context
org.activiti.engine.ActivitiException: condition expression returns non-Boolean: true (java.lang.String)
at org.activiti.engine.impl.el.UelExpressionCondition.evaluate(UelExpressionCondition.java:43)
at org.activiti.engine.impl.bpmn.behavior.ExclusiveGatewayActivityBehavior.leave(ExclusiveGatewayActivityBehavior.java:63)
at org.activiti.engine.impl.bpmn.behavior.FlowNodeActivityBehavior.execute(FlowNodeActivityBehavior.java:36)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute.execute(AtomicOperationActivityExecute.java:44)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:76)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:497)
意思是表达式返回的不是布尔值,确实不是布尔值,
在 approve.form 中vacationApproved确实要求是boolean类型的
<select name="vacationApproved">
<option value="true">Yes</option>
<option value="false">No</option>
</select>
<input type="hidden" name="vacationApproved_type" value="Boolean" />
我传递到后台的
String vacationApproved = request.getParameter("vacationApproved");
vacationApproved 是字符串 “true”,
可是流程文件中审批请假的这个用户任务后的这个分支节点的输入条件要求的表达式是
${vacationApproved}
流程文件片段如下
<sequenceFlow id="flow3" sourceRef="requestApprovedDecision" targetRef="sendApprovalMail">
<conditionExpression xsi:type="tFormalExpression">${vacationApproved}</conditionExpression>
</sequenceFlow>
看意思是要求vacationApproved是布尔类型的,可这个变量
是请假审批人提交表单的一个数据,这个数据只能是字符串型的,因为
formService 这个服务类提交用户任务表单的方法是
void submitTaskFormData(String taskId, Map<String, String>
properties);
只能传递字符串。
现在的问题就是我传递字符串过去后台报错说 返回值是字符串“true”,不是boolean 类型的,可是我也不能直接传递一个boolean 类型的过去呀,因为api 不允许。
怎么办?
请教了!
你页面下拉框获取的"true"为字符串需要你转换为boolean值,明白吗?