5.2 activiti任务监听器TaskListener

2023-11-07

1. 任务监听器定义

任务监听器用于在特定的任务相关事件发生时,执行自定义的Java逻辑或表达式

2.监听器监听的事件

  1. String EVENTNAME_CREATE = "create";创建):当任务已经创建,并且所有任务参数都已经设置时触发
  2. String EVENTNAME_ASSIGNMENT = "assignment";(指派):当任务已经指派给某人时触发。请注意:当流程执行到达用户任务时,create事件触发前,首先触发assignment事件。这看起来不是自然顺序,但是有实际原因的:当收到create事件时,我们通常希望查看任务的所有参数,包括办理人。 
  3. String EVENTNAME_COMPLETE = "complete"(完成):当任务已经完成,从运行时数据中删除前触发。
  4. String EVENTNAME_DELETE = "delete"(删除):在任务即将被删除前触发。请注意当任务通过completeTask正常完成时也会触发

注意:assignment事件比create先执行。

3. 任务监听实现方式——类class

实现接口org.activiti.engine.delegate.TaskListener

在流程定义文件中用class属性来指定该监听器

3.1 TaskListener源码

/**
 * @author Tom Baeyens
 */
public interface TaskListener extends Serializable {

  //create(创建):当任务已经创建,并且所有任务参数都已经设置时触发
  String EVENTNAME_CREATE = "create";
  /**assignment(指派):当任务已经指派给某人时触发。请注意:当流程执行到达用户任务时,
create事件触发前,首先触发assignment事件。这看起来不是自然顺序,
但是有实际原因的:当收到create事件时,我们通常希望查看任务的所有参数,包括办理人。**/
  String EVENTNAME_ASSIGNMENT = "assignment";
  //(完成):当任务已经完成,从运行时数据中删除前触发
  String EVENTNAME_COMPLETE = "complete";
  //(删除):在任务即将被删除前触发。请注意当任务通过completeTask正常完成时也会触发
  String EVENTNAME_DELETE = "delete";
  
  
  /**
   * Not an actual event, used as a marker-value for {@link TaskListener}s that should be called for all events,
   * including {@link #EVENTNAME_CREATE}, {@link #EVENTNAME_ASSIGNMENT} and {@link #EVENTNAME_COMPLETE} and {@link #EVENTNAME_DELETE}.
   */
  String EVENTNAME_ALL_EVENTS = "all";
  
  void notify(DelegateTask delegateTask);
}

xml文件中定义

<userTask id="usertask2" name="User Task" activiti:assignee="c">
      <extensionElements>
        <activiti:taskListener event="all" class="com.daling.ch1.listener.MyExecutionListener"></activiti:taskListener>
      </extensionElements>
</userTask>

3.2 类的定义

任务监听器中我们可以拿到DelegateTask对象,这个对象可以让我们操作activiti引擎中的一些东西,下面看一下DelegateTask类中的定义主要访法。 



import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

/**
 * 任务监听器用于在特定的任务相关事件发生时,执行自定义的Java逻辑或表达式
 *
 * 任务监听器支持下列属性:
 *  event(事件)(必填):任务监听器将被调用的任务事件类型。可用的事件有:
 *         create(创建):当任务已经创建,并且所有任务参数都已经设置时触发。
 *         assignment(指派):当任务已经指派给某人时触发。请注意:当流程执行到达用户任务时,create事件触发前,首先触发
 *         assignment事件。这看起来不是自然顺序,但是有实际原因的:当收到create事件时,我们通常希望查看任务的所有参数,包括
 *         办理人。
 *         complete(完成):当任务已经完成,从运行时数据中删除前触发。
 *         delete(删除):在任务即将被删除前触发。请注意当任务通过completeTask正常完成时也会触发
 *
 *   class:需要调用的代理类。这个类必须实现 org.activiti.engine.delegate.TaskListener 接口
 *
 *
 *   expression:(不能与class属性一起使用):指定在事件发生时要执行的表达式。可以为被调用的对象传递 DelegateTask 对象与事件名(使用 task.eventName )作为参数
 *
 *
 *
 *   delegateExpression:可以指定一个能够解析为 TaskListener 接口实现类对象的表达式。与服务任务类似
 *
 *
 */
@Slf4j
public class SiteReportUserTask implements TaskListener {
    private static final long serialVersionUID = 3654543511891213996L;

    @Override
    public void notify(DelegateTask delegateTask) {
        log.info("creattime: {}",delegateTask.getCreateTime());
        
        log.info("getProcessInstanceId: {}",delegateTask.getProcessInstanceId());


        log.info("数据库中的taskId主键: {}",delegateTask.getId());
        log.info("任务名称: {}",delegateTask.getName());
        delegateTask.setName("修改任务名称");

        log.info("获取任务的描述信息: {}",delegateTask.getDescription());
        delegateTask.setDescription("修改任务的描述信息");
        /**
         * lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high
         * [80..100] highest
         任务处理的优先级范围是0-100
         */
        log.info("任务处理的优先级范围是0-100: {}",delegateTask.getPriority());
        delegateTask.setPriority(1); /** 修改优先级*/

        log.info("获取流程实例id: {}",delegateTask.getProcessInstanceId());
        log.info("获取流程获取执行id: {}",delegateTask.getExecutionId());
        log.info("获取流程定义id: {}",delegateTask.getProcessDefinitionId());

     
        /** 添一个加候选人 */
       //void addCandidateUser(String userId);

        /** 添加候选人集合 */
        //void addCandidateUsers(Collection<String> candidateUsers);

        /** 添加候选组 */
        //void addCandidateGroup(String groupId);

        
        
        String eventName = delegateTask.getEventName();
        if (EVENTNAME_CREATE.endsWith(eventName)) {
            System.out.println("create=========");
        }else if (EVENTNAME_ASSIGNMENT.endsWith(eventName)) {
            System.out.println("assignment========");
        }else if (EVENTNAME_COMPLETE.endsWith(eventName)) {
            System.out.println("complete===========");
        }else if (EVENTNAME_DELETE.endsWith(eventName)) {
            System.out.println("delete=============");
        }

    }
}

3.3 监听器委托类DelegateTask

/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.activiti.engine.delegate;

import java.util.Collection;
import java.util.Date;
import java.util.Set;

import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.IdentityLinkType;

/**
 * @author Joram Barrez
 */
public interface DelegateTask extends VariableScope {

  /** DB id of the task. */
  String getId();
  
  /** Name or title of the task. */
  String getName();
  
  /** Change the name of the task. */
  void setName(String name);

  /** Free text description of the task. */
  String getDescription();
  
  /** Change the description of the task */
  void setDescription(String description);
  
  /** indication of how important/urgent this task is with a number between 
   * 0 and 100 where higher values mean a higher priority and lower values mean 
   * lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high 
   * [80..100] highest */
  int getPriority();
  
  /** indication of how important/urgent this task is with a number between 
   * 0 and 100 where higher values mean a higher priority and lower values mean 
   * lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high 
   * [80..100] highest */
  void setPriority(int priority);
  
  /** Reference to the process instance or null if it is not related to a process instance. */
  String getProcessInstanceId();
  
  /** Reference to the path of execution or null if it is not related to a process instance. */
  String getExecutionId();
  
  /** Reference to the process definition or null if it is not related to a process. */
  String getProcessDefinitionId();

  /** The date/time when this task was created */
  Date getCreateTime();
  
  /** The id of the activity in the process defining this task or null if this is not related to a process */
  String getTaskDefinitionKey();

  /** Indicated whether this task is suspended or not. */
  boolean isSuspended();

  /** The tenant identifier of this task */
  String getTenantId();

  /** The form key for the user task */
  String getFormKey();

  /** Change the form key of the task */
  void setFormKey(String formKey);
  
  /** Returns the execution currently at the task. */
  DelegateExecution getExecution();
  
  /** Returns the event name which triggered the task listener to fire for this task. */
  String getEventName();

  /** The current {@link org.activiti.engine.task.DelegationState} for this task. */
  DelegationState getDelegationState();
  
  /** Adds the given user as a candidate user to this task. */
  void addCandidateUser(String userId);
  
  /** Adds multiple users as candidate user to this task. */
  void addCandidateUsers(Collection<String> candidateUsers);
  
  /** Adds the given group as candidate group to this task */
  void addCandidateGroup(String groupId);
  
  /** Adds multiple groups as candidate group to this task. */
  void addCandidateGroups(Collection<String> candidateGroups);

  /** The {@link User.getId() userId} of the person responsible for this task. */
  String getOwner();
  
  /** The {@link User.getId() userId} of the person responsible for this task.*/
  void setOwner(String owner);
  
  /** The {@link User.getId() userId} of the person to which this task is delegated. */
  String getAssignee();
  
  /** The {@link User.getId() userId} of the person to which this task is delegated. */
  void setAssignee(String assignee);
  
  /** Due date of the task. */
  Date getDueDate();
  
  /** Change due date of the task. */
  void setDueDate(Date dueDate);
  
  /** The category of the task. This is an optional field and allows to 'tag' tasks as belonging to a certain category. */
  String getCategory();
	
  /** Change the category of the task. This is an optional field and allows to 'tag' tasks as belonging to a certain category. */
  void setCategory(String category);
  
  /**
   * Involves a user with a task. The type of identity link is defined by the given identityLinkType.
   * @param userId id of the user involve, cannot be null.
   * @param identityLinkType type of identityLink, cannot be null (@see {@link IdentityLinkType}).
   * @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
   */
  void addUserIdentityLink(String userId, String identityLinkType);
  
  /**
   * Involves a group with group task. The type of identityLink is defined by the given identityLink.
   * @param groupId id of the group to involve, cannot be null.
   * @param identityLinkType type of identity, cannot be null (@see {@link IdentityLinkType}).
   * @throws ActivitiObjectNotFoundException when the task or group doesn't exist.
   */
  void addGroupIdentityLink(String groupId, String identityLinkType);
  
  /**
   * Convenience shorthand for {@link #deleteUserIdentityLink(String, String)}; with type {@link IdentityLinkType#CANDIDATE}
   * @param userId id of the user to use as candidate, cannot be null.
   * @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
   */
  void deleteCandidateUser(String userId);
  
  /**
   * Convenience shorthand for {@link #deleteGroupIdentityLink(String, String, String)}; with type {@link IdentityLinkType#CANDIDATE}
   * @param groupId id of the group to use as candidate, cannot be null.
   * @throws ActivitiObjectNotFoundException when the task or group doesn't exist.
   */
  void deleteCandidateGroup(String groupId);
  
  /**
   * Removes the association between a user and a task for the given identityLinkType.
   * @param userId id of the user involve, cannot be null.
   * @param identityLinkType type of identityLink, cannot be null (@see {@link IdentityLinkType}).
   * @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
   */
  void deleteUserIdentityLink(String userId, String identityLinkType);
  
  /**
   * Removes the association between a group and a task for the given identityLinkType.
   * @param groupId id of the group to involve, cannot be null.
   * @param identityLinkType type of identity, cannot be null (@see {@link IdentityLinkType}).
   * @throws ActivitiObjectNotFoundException when the task or group doesn't exist.
   */
  void deleteGroupIdentityLink(String groupId, String identityLinkType);

  /**
   * Retrieves the candidate users and groups associated with the task.
   * @return set of {@link IdentityLink}s of type {@link IdentityLinkType#CANDIDATE}.
   */
  Set<IdentityLink> getCandidates();
}

4. 监听实现方式——表达式expression

使用activiti:taskListener元素的expression属性来指定监听器

4.1 普通表达式

4.1.1  定义表达式类

package org.jeecg.modules.activiti.ext.expression;

import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

import java.io.Serializable;

@Slf4j
public class TaskListenerExpression implements Serializable {
    private static final long serialVersionUID = 6880733208262796584L;

    public void execute(DelegateTask delegateTask) {
        log.info("creattime: {}", delegateTask.getCreateTime());

        log.info("getProcessInstanceId: {}", delegateTask.getProcessInstanceId());


        log.info("数据库中的taskId主键: {}", delegateTask.getId());
        log.info("任务名称: {}", delegateTask.getName());
        delegateTask.setName("修改任务名称");

        log.info("获取任务的描述信息: {}", delegateTask.getDescription());
        delegateTask.setDescription("修改任务的描述信息");
        /**
         * lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high
         * [80..100] highest
         任务处理的优先级范围是0-100
         */
        log.info("任务处理的优先级范围是0-100: {}", delegateTask.getPriority());
        delegateTask.setPriority(1); /** 修改优先级*/

        log.info("获取流程实例id: {}", delegateTask.getProcessInstanceId());
        log.info("获取流程获取执行id: {}", delegateTask.getExecutionId());
        log.info("获取流程定义id: {}", delegateTask.getProcessDefinitionId());


        /** 添一个加候选人 */
        //void addCandidateUser(String userId);

        /** 添加候选人集合 */
        //void addCandidateUsers(Collection<String> candidateUsers);

        /** 添加候选组 */
        //void addCandidateGroup(String groupId);


        String eventName = delegateTask.getEventName();
        if (TaskListener.EVENTNAME_CREATE.endsWith(eventName)) {
            System.out.println("create=========");
        } else if (TaskListener.EVENTNAME_ASSIGNMENT.endsWith(eventName)) {
            System.out.println("assignment========");
        } else if (TaskListener.EVENTNAME_COMPLETE.endsWith(eventName)) {
            System.out.println("complete===========");
        } else if (TaskListener.EVENTNAME_DELETE.endsWith(eventName)) {
            System.out.println("delete=============");
        }
    }
}

4.1.2 xml定义

 4.1.3 如何调用

在流程执行到某个阶段,或者启动流程实例的时候,用下面代码调用

Map<String,Object> map=new HashMap<>();
map.put("taskListenerExpression",new TaskListenerExpression());
runtimeService.startProcessInstanceByKey("taskListener_study2",map);

4.2 spring表达式

spring表达式只是对4.1的优化处理,我们只需要在自己定义的TaskListenerExpression类上加注解管理该bean。在表达式中直接调用。如下其他都不用改表:


@Slf4j
@Service("listenerSpringExpression")
public class TaskListenerExpression implements Serializable {
    private static final long serialVersionUID = 6880733208262796584L;

    public void execute(DelegateTask delegateTask) {
        log.info("creattime: {}", delegateTask.getCreateTime());

        log.info("getProcessInstanceId: {}", delegateTask.getProcessInstanceId());

xml处的调用也不需要改变。当任务执行到该节点的时候,会直接调用该spring管理的bean。

5. 监听器实现方式——委托表达式delegateExpression

委托表达式 和 表达式区别:

(1)委托表达式需要实现TaskListener和序列化接口

(2)xml中直接写实现类的变量名,不用写方法名称,默认调取接口方法名

5.1 表达式类的实现

package org.jeecg.modules.activiti.ext.expression;

import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

import java.io.Serializable;

/**
 * 监听器 委托表达式的实现
 */
@Slf4j
public class TaskListenerDelegateExpression implements TaskListener,Serializable {
    private static final long serialVersionUID = 6880733208262796584L;

    public void notify(DelegateTask delegateTask) {
        log.info("creattime: {}", delegateTask.getCreateTime());

        log.info("getProcessInstanceId: {}", delegateTask.getProcessInstanceId());


        log.info("数据库中的taskId主键: {}", delegateTask.getId());
        log.info("任务名称: {}", delegateTask.getName());
        delegateTask.setName("修改任务名称");

        log.info("获取任务的描述信息: {}", delegateTask.getDescription());
        delegateTask.setDescription("修改任务的描述信息");
        /**
         * lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high
         * [80..100] highest
         任务处理的优先级范围是0-100
         */
        log.info("任务处理的优先级范围是0-100: {}", delegateTask.getPriority());
        delegateTask.setPriority(1); /** 修改优先级*/

        log.info("获取流程实例id: {}", delegateTask.getProcessInstanceId());
        log.info("获取流程获取执行id: {}", delegateTask.getExecutionId());
        log.info("获取流程定义id: {}", delegateTask.getProcessDefinitionId());


        /** 添一个加候选人 */
        //void addCandidateUser(String userId);

        /** 添加候选人集合 */
        //void addCandidateUsers(Collection<String> candidateUsers);

        /** 添加候选组 */
        //void addCandidateGroup(String groupId);


        String eventName = delegateTask.getEventName();
        if (TaskListener.EVENTNAME_CREATE.endsWith(eventName)) {
            System.out.println("create=========");
        } else if (TaskListener.EVENTNAME_ASSIGNMENT.endsWith(eventName)) {
            System.out.println("assignment========");
        } else if (TaskListener.EVENTNAME_COMPLETE.endsWith(eventName)) {
            System.out.println("complete===========");
        } else if (TaskListener.EVENTNAME_DELETE.endsWith(eventName)) {
            System.out.println("delete=============");
        }
    }
}

5.2 xml流程文件的定义

<userTask id="sid-11585CC1-BD05-4589-8379-78A6EFA8DCCC" name="县区控尘办审批">
      <extensionElements>
        <activiti:taskListener event="create" delegateExpression="${taskListenerDelegateExpression}"></activiti:taskListener>
      </extensionElements>
</userTask>

5.3 监听器的使用

在流程到达该任务节点时,就会从流程变量中获取taskListenerDelegateExpression,并执行notify方法

Map<String,Object> map=new HashMap<>();
map.put("taskListenerDelegateExpression",new TaskListenerDelegateExpression());
runtimeService.startProcessInstanceByKey("taskListener_study2",map);

6. 字段属性使用

6.1 xml文件定义

 

 

 

<userTask id="sid-D92E1931-D96E-41EF-AF34-5FC059076F1D" name="办事处审批">
      <extensionElements>
        <activiti:taskListener event="complete" class="org.jeecg.modules.activiti.ext.listener.SiteReportUserTask">
          <activiti:field name="fieldNameA">
            <activiti:string><![CDATA[我是字符串内容666]]></activiti:string>
          </activiti:field>
        </activiti:taskListener>
      </extensionElements>
</userTask>

通过多次设置字段的值可以得知:

fieldNameA取值优先级: 第1个 字符串>第3个 字符串> 第二个 表达式

6.2 类中使用

@Slf4j
public class SiteReportUserTask implements TaskListener {
    private static final long serialVersionUID = 3654543511891213996L;

    private Expression fieldNameA;


    @Override
    public void notify(DelegateTask delegateTask) {

        Object o=fieldNameA.getValue(delegateTask);
        String str=fieldNameA.getExpressionText();


... ...

若在表达式中输入:${1==1},则上述代码输出是:o:true;str:${1==1}。自己体会,一个是值,一个是内容字符串。

7. 总结

  1. 一个用户任务节点可以创建多个监听器
  2. class类方式实现监听器,不需要在流程变量中加入监听器对象
  3. expression方式,监听器可以是一个普通的java类,但要实现序列化接口,需要在流程变量中加入监听器类的对象,或者加入spring容器中
  4. delegateExpression,监听器要同时实现TaskListener和序列化接口,需要在流程变量中加入监听器类的对象

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

5.2 activiti任务监听器TaskListener 的相关文章

  • activiti中的服务任务(ServiceTask)

    服务任务不同于用户任务 xff08 需人工处理 xff09 xff0c 服务任务一般是一段可自动执行的任务而无需人工干预 例如 xff1a 当用户完成 34 任务1 34 后 xff0c 想自动执行一个跑批任务处理后台数据库表的数据 xff
  • activiti修改流程定义二进制数据后需清缓存

    示例如下 package com zz flow utils import org activiti engine impl interceptor Command import org activiti engine impl inter
  • 使用activiti总结--发布,办理,查询

    接上一篇文章 xff0c 使用创建好的流程图 xff0c 总结一下activiti发布到查询使用的方法和测试代码 流程图 1 引用配置文件 activiti cfg xml xff0c 不引用或者引用失败的话在创建流引擎的时候会报空指针异常
  • IDEA教程之Activiti插件

    本文作者 Spring ZYL 文章来源 人生就是一个不断学习的过程 码农StayUp CSDN博客 SpringBoot全家桶 Java数据结构与算法分析 设计模式领域博主 版权声明 本文版权归作者所有 转载请注明出处 一 安装Activ
  • Activiti6.0学习实践(4)-流程引擎配置一

    在上一节 我们进行了一个hello world 的简单应用搭建 本节继续对activiti的一些重要组件进行更进一步的分析 目录 1 activiti工程骨架 1 2 添加demo类到骨架工程 1 3 创建基于骨架的maven工程 2 流程
  • activiti 动态分配任务候选人

    任务候选人是有权限对该任务进行操作的用户 可以使用TaskService addCandidateUser 或 addCandidateGroup 实现 可以在bpmn中进行配置 可以使用监听器方式 需要继承TaskListener 可以使
  • Activiti6.0学习实践(2)-源码工程构建

    上节对工作流和activiti有了一个基本认识 本节主要目的是构建源码工程 了解如何从git上创建本地的工程 同时对源码有个基本的了解 目录 1 克隆到本地 2 建立远程git库分支 3 导入到工程 4 源码基本结构 5 基于源码启动act
  • 万字详解:Activiti 工作流引擎

    点击上方 芋道源码 选择 设为星标 管她前浪 还是后浪 能浪的浪 才是好浪 每天 10 33 更新文章 每天掉亿点点头发 源码精品专栏 原创 Java 2021 超神之路 很肝 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网
  • 【activiti 入门】springboot 集成activiti6.0的demo

    环境 jdk 1 8 maven 3 0 IDEA插件之actiBPM springboot2 0 activiti6 0 mysql数据库 具体demo地址 https download csdn net download qq 3333
  • Activiti启动流程实例,runtimeService.startProcessInstanceByKey

    启动流程实例 添加进businessKey 本质 act ru execution表中的businessKey的字段要存入业务标识 public class BusinessKeyAdd public static void main St
  • 《5分钟说完一个概念》:什么是Bootstrap采用

    想知道中国人的平均身高 群体均值 群体方差为 每次抽样 1000 人 抽样了 次 每次抽样的 1000人 的平均身高是一次随机抽样 这
  • 2023最新版本Activiti7系列-身份服务

    身份服务 在流程定义中在任务结点的 assignee 固定设置任务负责人 在流程定义时将参与者固定设置在 bpmn 文件中 如果临时任务负责人变更则需要修改流程定义 系统可扩展性差 针对这种情况可以给任务设置多个候选人或者候选人组 可以从候
  • [Activiti 资料]Activiti 画图工具(activiti-designer,actiBPM,activiti-app)

    1 eclipse eclipse的画流程工具 activiti designer 1 1 直接下载Eclipse 或者下载已经安装了activiti designer的eclipse 既然你下载到了 怎么也礼节性的感谢一下哈 链接 htt
  • runtimeService 运行时服务组件

    在Activiti中 启动一个流程后 会创建一个流程实例 ProcessInstance继承Execution 两个都是接口 每个流程实例至少会有一个执行流 Execution 当流程实例没有流程分支时 一般情况下只会存在一个执行流 假设出
  • Activiti / Camunda 用变量改变边界计时器

    我有一个关于 Activiti Camunda 中用户任务的计时器边界事件的特殊问题 启动流程时 我使用流程变量设置计时器持续时间 并使用边界定义中的表达式来解析该变量 边界事件是在用户任务上定义的
  • 使用 Maven 集成 Activiti Modeler

    如何将 Activiti Modeler 集成到自己的 Web 应用程序中并保留 Maven 建议的所有优点 问题是Maven中的Activiti Modeler是Activiti Explorer的一部分 网上有一些问题来自那些想要开发自
  • 【工作流Activiti】Activiti的使用

    1 数据库支持 Activiti 运行必须要有数据库的支持 支持的数据库有 mysql oracle postgres mssql db2 h2 2 Activiti环境 我们直接在当前项目 guigu oa parent做Activiti
  • 如何将候选用户列表传递给 alfresco 中的 activiti 工作流任务?

    我希望能够传递作为任务候选者的用户列表 用户是从数据列表中检索的 不能作为一个组使用 Activiti candidateUsers 似乎是正确的方法 假设已获取用户并将其设置在变量 ipw reviwers 中
  • 将 Activiti 任务从旧流程迁移到新流程

    我有一个用于某些业务流程的 Activiti 项目 问题在于移民 现有流程有一些未完成的任务 我想通过添加新步骤来修改现有流程 现在 当我创建一个新任务时 这个新任务将根据更新的流程进行处理 而未完成的任务将按照旧流程进行处理 让我们看下面
  • Alfresco:在另一个任务中显示任务字段(查看它们)

    我正在将新的工作流程部署到 alfresco 4 0 e 我有一个 formkey cwf submitLeaveTask 的任务 这是代码

随机推荐

  • 认识sass

    一 认识sass SASS Syntactically Awesome Stylesheet 是一个CSS预处理器 有助于减少CSS的重复 节省时间 它是更稳定和强大的CSS扩展语言 描述文档的样式干净和结构 扩展了 CSS3 增加了规则
  • Java面向对象基础

    面向对象 学习内容 l 面向对象思想 l 类与对象及其使用 l 对象的内存图 l 成员变量和局部变量的区别 l 匿名对象 l 封装 private l this关键字 l 构造方法 l static关键字 l 继承 l 多态 l 抽象类 l
  • AVR单片机最小系统 基本硬件线路与分析

    AVR单片机最小系统 基本硬件线路与分析 AVR仿真器 AVR编程器 二合一 AVR JTAG与ISP 二合一V2 5 经典推荐 298 00元 富士通 MB90092 DEMO OSD视频字符叠加开发板 380 00元 国产 AVR JT
  • Wireshark使用技巧

    前言 Wireshark是一款图形界面的网络嗅探器 支持多种平台 是网络流量分析的利器 它的创始人是Gerald Combs 前身是Ethereal 作为开源项目经过众多开发者的完善它已经成为使用量最大的安全工具之一 最近刚把 Wiresh
  • 翰文进度计划软件横道图不显示文字_斑马进度计划2019,编制进度计划仅需8步!请收藏...

    斑马进度计划2019新功能简介 大突破 从此双代号网络计划支持父子结构啦 计划分分钟逐级拆解细化 前锋线也能自下而上反馈进度 进行多级管控里程碑预警啦 还有大家最心心念的TPM 全面计划管理 设计 招采 施工以及各专业全面联动计算 从此 项
  • 使用Crash工具分析 Linux dump文件

    前言 Linux 内核 以下简称内核 是一个不与特定进程相关的功能集合 内核的代码很难轻易的在调试器中执行和跟踪 开发者认为 内核如果发生了错误 就不应该继续运 行 因此内核发生错误时 它的行为通常被设定为系统崩溃 机器重启 基于动态存储器
  • 软件测试行业就业前景到底怎么样?

    软件测试就业前景非常好 目前IT行业对于软件测试方面的人才需求是非常大的 软件产品的质量对于一个软件来说是攸关生死的 各企业越来越重视软件产品质量 而软件测试的工作就是让软件质量越来越好 还有就是软件测试的工资待遇是非常好的 和其它职业相比
  • 《数据库系统概论》课程学习(26)——习题集(第1-14章)含答案

    数据库系统概论习题集 第一章 绪论 一 选择题 1 DBS是采用了数据库技术的计算机系统 DBS是一个集合体 包含数据库 计算机硬件 软件和 A 系统分析员 B 程序员 C 数据库管理员 D 操作员 2 数据库 DB 数据库系统 DBS 和
  • ssm框架整合(项目步骤)

    目录 一 前言 二 SSM框架 2 1 SSM整合到底整合什么 2 2 为什么要整合到一起 2 3 由谁来整合 2 4 ResponseBody注解的作用是什么 2 5 JSON 三 各框架应用场景 3 1 SpringMVC框架 3 2
  • 建立单链表并交换表中任意两个元素

    功能 建立单链表并交换表中任意两个元素 time 2017年3月12日15 07 25 include
  • 2021年 IEEE VIS 科学可视化与体渲染论文整理与分析

    因为最近工作的关系 需要研究一下IEEE VIS中2017年以后的与我之前主要方向 体渲染 医学可视化 有关的论文 我把这些年全部的论文进行了筛选和梳理 总共筛选出57篇论文 打算写一个文章来记录这些内容 这个栏目是2021年的九篇论文的介
  • MNIST数据库介绍及转换

    MNIST数据库介绍 MNIST是一个手写数字数据库 它有60000个训练样本集和10000个测试样本集 它是NIST数据库的一个子集 MNIST数据库官方网址为 http yann lecun com exdb mnist 也可以在win
  • springMVC ResponseBody 返回汉字乱码解决方案

    本文查考借鉴 http blog yimik com archives 899 js里通过ajax调用springmvc 后台返回的中文字符串乱码 通过搜索找解决方 大都让配置StringHttpMessageConverter这个bean
  • 本地JAR打镜像,并启动

    1 准备好jar 和Dockerfile文件 2 使用命令打镜像 docker build t wstest 3 查看镜像 4 由于服务是两个端口 使用以下命令 5 优化怎么随着docker的开启而启动 docker run restart
  • Maltrail恶意流量检测系统

    Maltrail恶意流量检测系统 项目介绍 项目GitHub地址 项目架构 项目数据集 运行方式 订阅源扩展 数据采集模块提取 项目介绍 maltrail是一款轻量级的恶意流量检测系统 其工作原理是通过采集网络中各个开源黑样本 包括IP 域
  • python操作sql

    from pymysql import connect def main 创建connection连接 conn connect host localhost port 3306 user root password 123456 data
  • 深入浅出UML类图(一)

    在UML 2 0的13种图形中 类图是使用频率最高的UML图之一 Martin Fowler在其著作 UML Distilled A Brief Guide to the Standard Object Modeling Language
  • Redis中key-value实现

    实现字典的方法有很多种 最简单的就是使用链表或数组 但是这种方式只适用于元素个数不多的情况下 要兼顾高效和简单性 可以使用哈希表 如果追求更为稳定的性能特征 并且希望高效地实现排序操作的话 则可以使用更为复杂的平衡树 在众多可能的实现中 R
  • JAVA8新特性--集合遍历之forEach

    java中的集合有两种形式Collection
  • 5.2 activiti任务监听器TaskListener

    1 任务监听器定义 任务监听器用于在特定的任务相关事件发生时 执行自定义的Java逻辑或表达式 2 监听器监听的事件 String EVENTNAME CREATE create 创建 当任务已经创建 并且所有任务参数都已经设置时触发 St