`
段slow
  • 浏览: 11213 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

浅谈activiti工作流

 
阅读更多
本文档是我综合了“前人”的经验以及我自己的一点儿心得所写。里面清楚的讲述了activiti从环境配置到真正项目的运行的详细过程。本人自知能力有限,发表此文章,有两个目的:第一,希望高人能指教一二;第二,供自己以后...
一:环境配置(前提:JBK、Tomcat和Eclispe、myeclipse已经安装好)
JDK1.5以上版本
Ant 1.8.1以上版本,运行自带的Demo必须.
Ant 的安装:
1、下载ant,并解压到E:\apache-ant-1.8.2     http://ant.apache.org/bindownload.cgi 2、配置环境变量  
  %ANT_HOME%:E:\apache-ant-1.8.2 (这里为你自己解压缩的目录)
  PATH:%ANT_HOME%\bin(这个设置是为了方便在dos环境下操作)
3、检测是否安装成功 
Activiti的安装:(下载的是整好的项目)
1、下载activiti-5.5.zip,并解压到E:\activiti-5.5      http://www.activiti.org/download.html 2、运行脚本,设置 Activiti 环境
  打开DOS窗口,cd到setup目录。
输入 ant demo.start,然后按 enter 键。
脚本完成后,会在浏览器内启动所有的 Activiti 的 web 应用。以 kermit/kermit 登陆。

引用
注意:在执行ant demo.start时,如果更换数据库,比如mysql(默认是H2),需要更新如下文件
1.build.properties
Java代码 
  
# The db property should refer to the type of database that  
# you want to use. Currently h2, MySQL(mysql), 
# Postgres SQL(postgres) and Oracle 10g (oracle) is supported. 

# SQL Server(mssql) is also supported, but is an EXPERIMENTAL feature. 
# IBM DB2(db2) is also supported, but is an EXPERIMENTAL feature. 

# When using oracle, follow the instructions described in the userguide, chapter 
# Configuration > Changing the database > Using Oracle in the demo setup 
db=mysql 
 
# The tx property refers to the transaction environment 
# you want to use.  Choose from {standalone} 
tx=standalone 
 
# Specify the version of Tomcat that you want to use. 
# We only tested with the given Tomcat version but in  
# theory any tomcat 6.0.x version should do fine. 
tomcat.version=6.0.32 
 
# If you have tomcat already downloaded, point the  
# downloads.dir property to that directly.  If tomcat is  
# not found in the downloads.dir, it will be automatically  
# downloaded there. 
# The downloads directory should be outside of /target/ 
# to avoid re-downloading after a clean 
downloads.dir=../../downloads 
 
# Remove this property or set it to disabled if you're not using Activiti Cycle 
feature.cycle=enabled 
 
# Remove this property or set it to disabled if you're not using Activiti Modeler 
feature.modeler=enabled 
  修改数据库类型为mysql   打开文件“setup\build.properties”修改db=mysql(默认为h2) 2、build.mysql.properties
Java代码 
db=mysql 
jdbc.driver=com.mysql.jdbc.Driver 
jdbc.url=jdbc:mysql://IP地址:3306/activiti?autoReconnect=true 
jdbc.username=所用数据库的用户名 
jdbc.password=所用数据库的密码 

遇到的问题:

一直提示9092端口被占用,其实本机上没有任何程序运行在端口9092,可以通过命令查看:netstat -an而且异常中提示的url不一定是tcp://localhost:9092,localhost可能是其他ip,最关键的就在这里,为什么会出现其他IP呢? 原因是在本机安装的了Vmware workstation,本机会出现三个网卡,如是就会出现异常。 把本机的两个虚拟网卡禁用就OK了。 这个问题比较难找到真实原因,因为问题提示太有误导性port may be in use
2、执行“ant demo.start”之前,需要创建数据库,否则会出现下边的问题:
3、执行“ant demo.start”完毕之后,自带的web应用访问不了,如下图:
原因:activiti-modeler-5.5.war不会自动发布,导致访问不了
(自己写)安装Activiti的Eclipse或者myeclipse插件 直接Update就行 http://activiti.org/designer/update/
Eclipse 3.6.2以上版本
Myeclipse8.5或者myeclipse 9.0版本的
支持的数据库
以下是Activiti使用参考数据库类型(区分大小写!)。
Activiti数据库类型 版本测试 JDBC URL示例 注释
H2 1.2.132 jdbc:h2:tcp://localhost/activiti 默认配置的数据库
MySQL 5.1.11 jdbc:mysql://localhost:3306/activiti 测试使用的mysql - connetor Java数据库驱动程序
Oracle 10.2.0 jdbc:oracle:thin:@localhost:1521:xe
POSTGRES 8.4 jdbc:postgresql://localhost:5432/activiti
DB2 DB2 9.7中使用db2jcc4 jdbc:db2://localhost:50000/activiti
MSSQL 2008使用JDBC JTDS - 1.2.4 jdbc:jtds:sqlserver://localhost:1433/activiti
·下面的是数据库表结构:
一、数据库建表:
      建表说明目前省略
数据库表的命名
Acitiviti数据库中表的命名都是以ACT_开头的。第二部分是一个两个字符用例表的标识。此用例大体与服务API是匹配的。
ACT_RE_*:’RE’表示repository。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。
ACT_RU_*:’RU’表示runtime。这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的数据。Activiti只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。
ACT_ID_*:’ID’表示identity。这些表包含标识的信息,如用户,用户组,等等。
ACT_HI_*:’HI’表示history。就是这些表包含着历史的相关数据,如结束的流程实例,变量,任务,等等。
ACT_GE_*:普通数据,各种情况都使用的数据。
二、数据库表结构说明:
1、用建模工具反向出来的数据库表结构图如下:
    



2、数据库表结构说明:
·             ACT_GE_PROPERTY:属性数据表。存储整个流程引擎级别的数据。
1. NAME_:属性名称
2. VALUE_:属性值
3. REV_INT:版本号?
·             ACT_GE_BYTEARRAY:用来保存部署文件的大文本数据的。
1. ID_:资源文件编号,自增长
2. REV_INT:版本号?
3. NAME_:资源文件名称
4. DEPLOYMENT_ID_:来自于父表ACT_RE_DEPLOYMENT中的主键
5. BYTES_:大文本类型,存储文本字节流
·             ACT_RE_DEPLOYMENT:用来存储部署时需要被持久化保存下来的信息。
1. ID_:部署编号,自增长
2. NAME_:部署的包名称
3. DEPLOY_TIME_:部署时间
·             ACT_RE_PROCDEF:业务流程定义数据表。
1. ID_:流程ID,由“流程编号:流程版本号:自增长ID ” 组成
2. CATEGORY_:流程命令空间(该编号就是流程文件targetNamespace的属性值)
3. NAME_:流程名称(该编号就是流程文件process元素的name属性值)
4. KEY_:流程编号(该编号就是流程文件process元素的id属性值)
5. VERSION_:流程版本号(由程序控制,新增即为1,修改后依次加1来完成的)
6. DEPLOYMENT_ID_:部署编号
7. RESOURCE_NAME_:资源文件名称
8. DGRM_RESOURCE_NAME_:图片资源文件名称
9. HAS_START_FORM_KEY_:是否有Start Form Key。
注意:此表与ACT_RE_DEPLOYMENT是多对一的关系,即,一个部署的bar包里可能包含多个流程定义文件,每个流程定义文件都会有一条记录在ACT_RE_PROCDEF表内,每条流程定义的数据,都会对应ACT_GE_BYTEARRAY表内的一个资源文件和PNG图片文件。与ACT_GE_BYTEARRAY的关联是通过程序用ACT_GE_BYTEARRAY.NAME_与ACT_RE_PROCDEF.RESOURCE_NAME_完成的,在数据库表结构内没有体现。
·             ACT_ID_GROUP:用来保存用户组信息。
1. ID_:用户组名
2. REV_INT:版本号?
3. NAME_:用户组描述信息
4. TYPE_:用户组类型
·             ACT_ID_MEMBERSHIP:用来保存用户分组信息。
1. USER_ID_:用户名
2. GROUP_ID_:用户组名
·             ACT_ID_USER:用来保存用户信息。
1. ID_:用户名
2. REV_INT:版本号?
3. FIRST_:用户名称
4. LAST_:用户姓氏
5. EMAIL_:邮箱
6. PWD_:登录密码
·             ACT_RU_EXECUTION:
1. ID_:
2. REV_:版本号?
3. PROC_INST_ID_:流程实例编号
4. BUSINESS_KEY_:业务编号
5. PARENT_ID_:
6. PROC_DEF_ID_:流程ID
7. SUPER_EXEC_:
8. ACT_ID_:
9. IS_ACTIVE_:
10.            IS_CONCURRENT_:
11.            IS_SCOPE_:
·             ACT_RU_JOB:运行时定时任务数据表。
1. ID_:
2. REV_:
3. TYPE_:
4. LOCK_EXP_TIME_:
5. LOCK_OWNER_:
6. EXCLUSIVE_:
7. EXECUTION_ID_:
8. PROCESS_INSTANCE_ID_:
9. RETRIES_:
10.            EXCEPTION_STACK_ID_:
11.            EXCEPTION_MSG_:
12.            DUEDATE_:
13.            REPEAT_:
14.            HANDLER_TYPE_:
15.            HANDLER_CFG_:
·             ACT_RU_TASK:运行时任务数据表。
1. ID_:
2. REV_:
3. EXECUTION_ID_:
4. PROC_INST_ID_:
5. PROC_DEF_ID_:
6. NAME_:
7. DESCRIPTION_:
8. TASK_DEF_KEY_:
9. ASSIGNEE_:
10.            PRIORITY_:
11.            CREATE_TIME_:
·             ACT_RU_IDENTITYLINK:任务参与者数据表。主要存储当前节点参与者的信息。
1. ID_:
2. REV_:
3. GROUP_ID_:
4. TYPE_:
5. USER_ID_:
6. TASK_ID_:
·             ACT_RU_VARIABLE:运行时流程变量数据表。
1. ID_:
2. REV_:
3. TYPE_:
4. NAME_:
5. EXECUTION_ID_:
6. PROC_INST_ID_:
7. TASK_ID_:
8. BYTEARRAY_ID_:
9. DOUBLE_:
10.            LONG_:
11.            TEXT_:
12.            TEXT2_:
·             ACT_HI_PROCINST:
·             ACT_HI_ACTINST:
·             ACT_HI_TASKINST:
·             ACT_HI_DETAIL:
3、结论及改造建议
 
流程文件部署主要涉及到3个表,分别是:ACT_GE_BYTEARRAY、ACT_RE_DEPLOYMENT、ACT_RE_PROCDEF。主要完成“部署包”-->“流程定义文件”-->“所有包内文件”的解析部署关系。从表结构中可以看出,流程定义的元素需要每次从数据库加载并解析,因为流程定义的元素没有转化成数据库表来完成,当然流程元素解析后是放在缓存中的,具体的还需要后面详细研究。
流程定义中的java类文件不保存在数据库里 。
组织机构的管理相对较弱,如果要纳入单点登录体系内还需要改造完成,具体改造方法有待研究。
运行时对象的执行与数据库记录之间的关系需要继续研究
历史数据的保存及作用需要继续研究。
Act_Execution Act_task Act_TaskInvolement Act_Job Act_Variable这五张表。 这五张表在执行完所谓的”部署“逻辑后,是不会被填上任何值的。那什么时候这些表会被填充上值呢? 当我们根据一个叫做ProcessService(在jBPM中,这个类是ExecutionService)的类,来真正启动(Start)一个流程 时,这些表中才会被根据你定义的流程定义,填充上相应的记录。 一个不精确的比喻,在Activiti中,流程定义和流程执行实例,就像Java中的Class何Class Instance关系一样,根据一个流程定义,可以启动多个流程实例,供不同业务需求使用;一个类,当然可以有多个运行时实例,供不同需求使用。 需要多说一点,Act_TaskInvolement这张表直译过来就是,任务参与者,所以它存的是:和一个流程中,一个具体动作(Activity)相 关的用户(User)和角色(Group)的信息,即:当前节点参与者的信息。其他的表,也可以顾名思义了吧,就是存和一个具体动作相关的参数以及作业的 信息。  最后强调一点:这五张表有点像即擦即用的Flash存储介质哦。 什么意思,一个流程假设有多个动作(任务、节点......叫啥也行)组成,那么这五张表只是存储当前流程实例中,”活动(Active)行为“的相关数 据,如果现在活动的行为已经从A节点流到B节点了,那么,与A节点相关的所有信息是会从这4张表(不包含Act_Execution,流程实例全部完成, 相关记录才会删除;而不是一个动作完成)中被删除的!!!!
Activiti的持久化方式:
Activiti使用Mybatis3做持久化工作,可以在配置中设置流程引擎启动时创建表。
Activiti-administrator:自带的用户管理系统,维护用户和组,需要配置数据连接参数,在activiti-administrator\WEB-INF\applicationContext.xml中,并加入JDBC驱动包。
Activiti-cycle:PVM活动检测的,由activiti-rest提供服务,不需配置。
Activiti-explorer:可以查看用户任务和启动流程,由activiti-rest提供服务,不需配置。
Activiti-kickstart:简单的点对点流程定义维护工具,需要配置数据连接,把activiti.cfg.xml文件放在classes下,并加入驱动包
Activiti-modeler:在线编辑和维护流程定义的工具,最后以文件夹的方式部署,需要配置:activiti-modeler\WEB-INF\classes\configuration.properties文件。
Activiti-probe:PVM的观测服务,由activiti-rest提供服务,不需配置。可以查看deployment、processdefinition、processinstance、database。
Activiti-rest:其它几个应用的服务提供者,需要配置数据连接,把activiti.cfg.xml文件放在classes下,并加入驱动包。
关键对象:
Deployment:流程部署对象,部署一个流程是创建。
processDefinitions:流程定义,部署成功后自动创建。
ProcessInstances:流程实例,启动流程是创建。
Task:任务,在activiti中的task仅指有角色参与的任务,即定义中的UserTask。
Execution:执行计划,流程实例和流程执行中的所有节点都是Execution,如UserTask、ServiceTask等。
服务接口:
ProcessEngine:流程引擎接口,提供流程管理和运作的所有接口。
RuntimeService:运行时服务接口,提供流程启动服务,运行中流程查询,运行变量设置和获取。
TaskService:用户任务接口(UserTask),提供运行时任务查询、领取、完成、删除及变量设置用户管理等服务。
IdentityService:用户和组管理接口。
ManagementService:流程引擎管理接口。
HistoryService:流程处理查询接口,包括执行中流程查询和历史流程查询。
简单入门:
Activiti的实用意义: Activiti是JBPM的原创者的团队编写的,实际上它才是JBPM“血统”的继承者。而如今的JBPM5所用的几乎是Drools Flow的源码。因此一直在用JBPM的用户更倾向于使用Activiti,需要注意的是Activiti用的是BPMN的流程定义语言BPEL而非当初 的JBDL了。 二、Activiti的designer在eclipse中的安装: 打开 HelpInstall New Software。在如下面板中,点击 Add 按钮,然后填写下列字段:  Name:Activiti BPMN 2.0 designer Location:http://activiti.org/designer/update/  务必不要选中”Contact all updates sites..”,因为所有必需的插件都能从 Activiti 更新站点下载。 三、Activiti整合MySql数据库的方法 要将演示程序设置配置到不同的数据库,或生成不同的数据库的配置文件,按如下步骤:   编辑 setup/build.propertyies,将 db 参数修改成你的数据库类型{oracle | mysql | postgres | h2 | db2 | mssql}。 编辑 setup/build.${db}.propertyies,将 JDBC 连接参数修改成你安装的数据库的参数。 要想根据你在 build.*.properties 文件指定的属性来创建数据的配置文件,请在(开始->运行->CMD)setup 文件内运行:  ant cfg.create 可以在 setup/build/activti.cfg 内找到生成的配置文件。同时,方便起见,可以在 setup/build 下找到包含了配置文件的 jar 文件 activiti-cfg.jar。 四、部署Activiti实例和Activiti的web designer部署 打开控制台,ant demo.start 这时则开始建立数据库,部署实例到eclipse,部署designer到tomcat服务器,这里的tomcat服务器在{%activiti-5.6%}\apps\apache-tomcat-6.0.32下。 如果之前更改了数据库, Eclipse中需要将实例的配置文件activiti.cfg.xml的内容改为{%activiti-5.6%}\setup\build\activiti-cfg\activiti.cfg.xml的内容。 为了使Activiti KickStart 能够正常运行,我们需要单独更改它的数据库驱动程序activiti.cfg.jar (正确配置的jar位于{%activiti-5.6%}/setup/build/下) ,并将其置于apps/apache-tomcat-6.x/webapps/activiti-kickstart/WEB-INF/lib 文件夹下。同样,必须将数据库驱动程序置于同一文件夹下。 可以在 setup/files/dependencies/libs/下找到你的数据库驱动程序(除了 Oracle)。 五、Activiti web designer以及部署到eclipse的实例介绍 应用名称 URL 描述 Activiti Probe http://localhost:8080/activiti-probe 管理员管理控制台。使用该工具查看配置好的流程引擎是否正确初始化,以及数据库内容。 Activiti Explorer http://localhost:8080/activiti-explorer 流程引擎用户控制台。使用该工具查看您的个人任务、候选人任务,以及完成的任务。 Activiti Cycle http://localhost:8080/activiti-cycle Activiti 协助工具。使用该工具浏览资料库以及执行模型格式之间的转换。 Activiti Modeler http://localhost:8080/activiti-modeler 基于Web 的流程设计工具。使用该工具绘制BPMN2.0 规范的流程定义文件。(对浏览器有版本要求) Activiti KickStart http://localhost:8080/activiti-kickstart Activiti KickStart 是利用 Activiti 引擎的可用构造的子集来快速创建’临时安排的(adhoc)’业务流程的一个基于 web 的工具。  activiti-engine-examples:该套示例展示了 Activiti 最常用的用法:BPMN 流程定义和流程的执行被存储在数据库中, 并且示例中使用了持久化 API。  activiti-spring-examples:这些示例展示了在 Spring 环境下如何使用 Activiti 引擎。  activiti-groovy-examples:这些示例展示了 groovy 的依赖库以及一个使用 groovy 脚本的流程。  activiti-jpa-examples:这些示例展示了依赖库以及 Activiti 中如何使用 JPA。  activiti-cxf-examples:这些示例展示了依赖库以及在 Activiti 中如何使用 web 服务。  activiti-cycle-examples:此项目内含有一个关于 Activiti Cycle 的演示示例。  activiti-modeler-examples:在演示程序安装内 Activiti Modeler 配置的模型库文件。
通过 ProcessEngineBuilder  读取 activiti 的配置文件,就可以生成流程引擎实例。
通过流程引擎实例 processEngine, 我们就可以通过 getXXXService() 取得各种包含 workflow/BPM  方法的 service 。
RepositoryService  : 提供方法获取各种流程和部署文件的信息 .
TaskService :  提供对任务相关的各种操作
identityService :  管理用户和用户组。
FormService :  获取或者绑定数据到流程实例上
RuntimeService :  提供操作部署文件,流程文件和流程实例的方法 .
ManagementService :  提供管理员对流程引擎的监控,和流程引擎服务应用无关。
HistoryService :  提供正在执行和过去执行的各种流程实例信息
ProcessEngines.getDefaultProcessEngine()会在第一次被调用时初始并构建process engine,接下来对该方法的调用返回的都
是同一个流程引擎。利用ProcessEngines.init()、ProcessEngines.destroy()可以正确创建、关闭流程引擎。
ProcessEngines 会浏览所有activiti.cfg.xml 和activiti-context.xml 文件。对于那些activiti.cfg.xml 文件,将以Activiti 特有的方
式来构建流程引擎:
ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream).buildProcessEngine()。对于那些
activiti-context.xml 文件,将以Spring  的方式来构建流程引擎:首先,创建spring 应用上下文;然后,从该上下文中获取流程引擎。


绘制流程图
创建完后会发现它自动把流程图放到main.resources.diagrams 包下面了,如果不想放在这下面可以直接移动过去。本人移动到了activiti.process.def包下面,这样比较符合编码规范。
接下来就是打开创建的流程图,开始绘制了。
按照上面绘制完后,就该编写相应的代码了。
package activiti.process; 
 
import org.activiti.engine.delegate.DelegateExecution; 
import org.activiti.engine.delegate.JavaDelegate; 
 
public class ProcessHelloWorld implements JavaDelegate { 
 
    @Override 
    public void execute(DelegateExecution arg0) throws Exception { 
        System.out.println("HelloWorld"); 
    } 
 

然后给 HelloWorld这个节点指定相应的执行相应的代码,需要打开流程图HelloWorld.activiti 然后点击HelloWorld节点 在下面的点开Main config选项卡里面指定Service class 为刚才写的流程代码。这样当流程走到这一步的时候就会执行这个类里面的execute方法。

接下来咱们需要做的就是发布流程以及启动流程了。
编写ProcessUtil封装一些方法,方便调用。

package activiti.process; 
 
import java.util.HashMap; 
 
/**
* 与流程有关的工具类


*/ 
public class ProcessUtil { 
    /**
     * 发布流程的方法
     */ 
    public static void deploy() { 
        RepositoryService service = (RepositoryService) CommonUtil.getBean("repositoryService"); 
        service.createDeployment().addClasspathResource("activiti/process/def/HelloWorld.bpmn20.xml") 
                .addClasspathResource("activiti/process/def/HelloWorld.png").deploy(); 
    } 
 
    /**
     * 启动流程
     */ 
    public static String start() { 
        RuntimeService service = (RuntimeService) CommonUtil.getBean("runtimeService"); 
        ProcessInstance instance = service.startProcessInstanceByKey("HelloWorld"); 
 
        return instance.getProcessInstanceId(); 
    } 
}
CommonUtil代码

public class CommonUtil implements ApplicationContextAware { 
    private static ApplicationContext springFactory = null; 
 
    public static Object getBean(String name) { 
        return springFactory.getBean(name); 
    } 
 
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
        springFactory = applicationContext; 
    } 
}
编写相应的servlet
public class ProcessAction extends HttpServlet { 
private static final long serialVersionUID = 1L; 
public ProcessAction() { 
super(); 
}   
 
/**
* @see HttpServlet#service(HttpServletRequest request, HttpServletResponse
*      response)
*/ 
@Override 
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
String cmd = request.getParameter("cmd"); 
String page = null; 
if ("deploy".equals(cmd)) { 
ProcessUtil.deploy(); 
request.setAttribute("result", "流程发布成功"); 
page = "success.jsp"; 
} else if ("start".equals(cmd)) { 
String id = ProcessUtil.start(); 
request.setAttribute("result", "流程启动成功,流程ID:" + id); 
page = "success.jsp"; 
}  
request.getRequestDispatcher(page).forward(request, response); 

}
相应的页面index.jsp
[html]view plaincopyprint?

<%@ page language="java" contentType="text/html; charset=utf-8" 
    pageEncoding="utf-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
<title>流程测试</title> 
</head> 
<body> 
    <form action="process" method="post"> 
        <input type="radio" name="cmd" value="deploy">发布流程</input>  
        <input type="radio" name="cmd" value="start">启动流程</input>  
        <input type="radio" name="cmd" value="view">查看当前启动用户流程</input>  
        <input type="submit" value="提交"> 
    </form> 
</body> 
</html> 
success.jsp
[html]view plaincopyprint?

<%@ page language="java" contentType="text/html; charset=utf-8" 
    pageEncoding="utf-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
<title>成功</title> 
</head> 
<body> 
    处理结果:<%=request.getAttribute("result") %> 
    <a href="index.jsp">返回</a> 
</body> 
</html> 
web.xml配置
<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> 
  <context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
<span style="white-space:pre">    </span>classpath*:*.xml 
    </param-value> 
  </context-param> 
  <listener> 
    <listener-class> 
            org.springframework.web.context.ContextLoaderListener 
        </listener-class> 
  </listener> 
  <servlet> 
    <servlet-name>ProcessAction</servlet-name> 
    <servlet-class>com.hollycrm.servlet.ProcessAction</servlet-class> 
  </servlet> 
  <servlet-mapping> 
    <servlet-name>ProcessAction</servlet-name> 
    <url-pattern>/process</url-pattern> 
  </servlet-mapping> 
</web-app>
至此编码工作已经全部完成,发布应用进入index.jsp,首先点击发布流程。然后再点击启动流程。看看是不是控制台输出了HelloWorld! 因为ServiceTask
为自动任务不需要人工干预,所以会自动执行。启动流程以后直接进入到了HellorWorld执行完后流程也就结束了。
在activiti中每一个用户属于一个用户组,不同的用户拥有不同的权限,不同的权限可以有不同的操作,因此请求的资源路径和登录的安全验证相当的重要。需要添加相关的验证。
       原理实现REST的org.restlet.Application接口实现,实现REST访问方式唯一的入口点,同时添加相关的权限验证。然后再web.xml配置即可。

web.xml配置如下:<?xml version="1.0" encoding="UTF-8"?> 
<web-app id="WebApp_ID" version="2.4" 
            xmlns="http://java.sun.com/xml/ns/j2ee" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
                 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 
 
  <display-name>Activiti REST</display-name>
  
  <listener>
    <listener-class>org.activiti.rest.servlet.ActivitiServletContextListener</listener-class>
  </listener>
 
  <!-- Restlet adapter --> 
  <servlet> 
    <servlet-name>RestletServlet</servlet-name> 
    <servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
    <init-param>
      <!-- Application class name -->
      <param-name>org.restlet.application</param-name>
      <param-value>org.activiti.rest.application.ActivitiRestApplication</param-value>
    </init-param>
  </servlet>
 
  <!-- Catch all requests --> 
  <servlet-mapping> 
    <servlet-name>RestletServlet</servlet-name> 
    <url-pattern>/service/*</url-pattern> 
  </servlet-mapping> 
</web-app>





代码如下:
package org.activiti.rest.application;

import org.activiti.rest.api.ActivitiUtil;
import org.activiti.rest.api.DefaultResource;
import org.activiti.rest.api.engine.ProcessEngineResource;
import org.activiti.rest.api.identity.GroupResource;
import org.activiti.rest.api.identity.GroupUsersResource;
import org.activiti.rest.api.identity.LoginResource;
import org.activiti.rest.api.identity.UserGroupsResource;
import org.activiti.rest.api.identity.UserPictureResource;
import org.activiti.rest.api.identity.UserResource;
import org.activiti.rest.api.identity.UserSearchResource;
import org.activiti.rest.api.management.JobExecuteResource;
import org.activiti.rest.api.management.JobResource;
import org.activiti.rest.api.management.JobsExecuteResource;
import org.activiti.rest.api.management.JobsResource;
import org.activiti.rest.api.management.TableDataResource;
import org.activiti.rest.api.management.TableResource;
import org.activiti.rest.api.management.TablesResource;
import org.activiti.rest.api.process.ProcessDefinitionFormResource;
import org.activiti.rest.api.process.ProcessDefinitionPropertiesResource;
import org.activiti.rest.api.process.ProcessDefinitionsResource;
import org.activiti.rest.api.process.ProcessInstanceDiagramResource;
import org.activiti.rest.api.process.ProcessInstanceResource;
import org.activiti.rest.api.process.ProcessInstancesResource;
import org.activiti.rest.api.process.StartProcessInstanceResource;
import org.activiti.rest.api.repository.DeploymentDeleteResource;
import org.activiti.rest.api.repository.DeploymentUploadResource;
import org.activiti.rest.api.repository.DeploymentsDeleteResource;
import org.activiti.rest.api.repository.DeploymentsResource;
import org.activiti.rest.api.task.TaskAddResource;
import org.activiti.rest.api.task.TaskAttachmentAddResource;
import org.activiti.rest.api.task.TaskAttachmentResource;
import org.activiti.rest.api.task.TaskFormResource;
import org.activiti.rest.api.task.TaskOperationResource;
import org.activiti.rest.api.task.TaskPropertiesResource;
import org.activiti.rest.api.task.TaskResource;
import org.activiti.rest.api.task.TaskUrlAddResource;
import org.activiti.rest.api.task.TasksResource;
import org.activiti.rest.api.task.TasksSummaryResource;
import org.restlet.Application;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
import org.restlet.data.ChallengeScheme;
import org.restlet.routing.Router;
import org.restlet.security.ChallengeAuthenticator;
import org.restlet.security.SecretVerifier;
import org.restlet.security.Verifier;

/**
* @author Tijs Rademakers
*/
public class ActivitiRestApplication extends Application {
 
  private ChallengeAuthenticator authenticator;

  /**
   * Creates a root Restlet that will receive all incoming calls.
   */
  @Override
  public synchronized Restlet createInboundRoot() {
    Verifier verifier = new SecretVerifier() {

      @Override
      public boolean verify(String username, char[] password) throws IllegalArgumentException {
        boolean verified = ActivitiUtil.getIdentityService().checkPassword(username, new String(password));
        return verified;
      }
    };
    authenticator = new ChallengeAuthenticator(null, true, ChallengeScheme.HTTP_BASIC,
          "Activiti Realm") {
     
      @Override
      protected boolean authenticate(Request request, Response response) {
        if (request.getChallengeResponse() == null) {
          return false;
        } else {
          return super.authenticate(request, response);
        }
      }
    };
    authenticator.setVerifier(verifier);
   
    Router router = new Router(getContext());

    router.attachDefault(DefaultResource.class);
   
    router.attach("/process-engine", ProcessEngineResource.class);
   
    router.attach("/login", LoginResource.class);
   
    router.attach("/user/{userId}", UserResource.class);
    router.attach("/user/{userId}/groups", UserGroupsResource.class);
    router.attach("/user/{userId}/picture", UserPictureResource.class);
    router.attach("/users/{searchText}", UserSearchResource.class);
   
    router.attach("/group/{groupId}", GroupResource.class);
    router.attach("/groups/{groupId}/users", GroupUsersResource.class);
   
    router.attach("/process-definitions", ProcessDefinitionsResource.class);
    router.attach("/process-instances", ProcessInstancesResource.class);
    router.attach("/process-instance", StartProcessInstanceResource.class);
    router.attach("/processInstance/{processInstanceId}", ProcessInstanceResource.class);
    router.attach("/processInstance/{processInstanceId}/diagram", ProcessInstanceDiagramResource.class);
    router.attach("/process-definition/{processDefinitionId}/form", ProcessDefinitionFormResource.class);
    router.attach("/process-definition/{processDefinitionId}/properties", ProcessDefinitionPropertiesResource.class);
   
    router.attach("/tasks", TasksResource.class);
    router.attach("/tasks-summary", TasksSummaryResource.class);
    router.attach("/task", TaskAddResource.class);
    router.attach("/task/{taskId}", TaskResource.class);
    router.attach("/task/{taskId}/form", TaskFormResource.class);
    router.attach("/task/{taskId}/attachment", TaskAttachmentAddResource.class);
    router.attach("/task/{taskId}/url", TaskUrlAddResource.class);
    router.attach("/task/{taskId}/{operation}", TaskOperationResource.class);
   
    router.attach("/attachment/{attachmentId}", TaskAttachmentResource.class);
   
    router.attach("/form/{taskId}/properties", TaskPropertiesResource.class);
   
    router.attach("/deployments", DeploymentsResource.class);
    router.attach("/deployment", DeploymentUploadResource.class);
    router.attach("/deployments/delete", DeploymentsDeleteResource.class);
    router.attach("/deployment/{deploymentId}", DeploymentDeleteResource.class);
   
    router.attach("/management/jobs", JobsResource.class);
    router.attach("/management/job/{jobId}", JobResource.class);
    router.attach("/management/job/{jobId}/execute", JobExecuteResource.class);
    router.attach("/management/jobs/execute", JobsExecuteResource.class);
   
    router.attach("/management/tables", TablesResource.class);
    router.attach("/management/table/{tableName}", TableResource.class);
    router.attach("/management/table/{tableName}/data", TableDataResource.class);
   
    authenticator.setNext(router);
   
    return authenticator;
  }
 
  public String authenticate(Request request, Response response) {
    if (!request.getClientInfo().isAuthenticated()) {
      authenticator.challenge(response, false);
      return null;
    }
    return request.getClientInfo().getUser().getIdentifier();
  }
}

分享到:
评论
2 楼 零零发发 2018-07-12  
Activiti6.0工作流引擎深度解析与实战
网盘地址:https://pan.baidu.com/s/1hZYXtRuABch0Dy1gpra2UA 密码: 6ncd
备用地址(腾讯微云):https://share.weiyun.com/5Z7sAqb 密码:8pwrkb

基于Activiti5工作流实战企业协同OA办公系统
网盘地址:https://pan.baidu.com/s/1PtIrCCCPVYEkDLZ5d-5qhg 密码: wc2g
1 楼 jackyrong 2012-11-02  
请问能使用ibatis2+spring 2.5.6结合acitivi么?

相关推荐

    activiti工作流(超详细)

    activiti工作流文档,超详细,从0基础开始入门,包括数据库介绍、核心api等介绍,满足日常开发所需

    Activiti工作流面试相关知识

    Activiti工作流引擎是一款开源的企业级业务流程管理(BPM)和工作流系统,它为组织提供了一种灵活、可扩展的方式来设计、执行和管理业务流程。在面试中,了解Activiti的核心服务对于理解其工作原理和实际应用至关...

    Activiti工作流教程

    Activiti工作流课程Activiti工作流课程Activiti工作流课程Activiti工作流课程Activiti工作流课程Activiti工作流课程

    Activiti工作流课程.pdf

    Activiti工作流课程.pdf Activiti工作流课程.pdf是关于Activiti工作流的详细介绍,涵盖了工作流的概念、Activiti的介绍、工作流引擎、BPMN业务流程建模与标注、数据库支持等方面的知识点。 一、工作流的概念 工作...

    activiti工作流课程

    ### Activiti工作流知识点概述 #### 一、工作流概念及其执行过程 1. **工作流定义**: - 工作流是指“业务过程的部分或整体在计算机应用环境下的自动化”。具体而言,它旨在通过预定义的规则来自动处理文档、信息...

    Activiti工作流引擎入门

    Activiti工作流引擎是Java平台上的一个开源工作流管理系统,专为简化业务流程自动化而设计。它使用BPMN(Business Process Model and Notation)2.0标准进行流程建模,使得非技术人员也能理解并创建复杂的业务流程。...

    activiti工作流PPT

    Activiti作为一个工作流引擎,允许开发者通过编程或使用图形化工具定义、执行和管理这些流程。 在Activiti中,流程定义是用BPMN 2.0(Business Process Model and Notation)语言编写的,这是一种国际标准,用于...

    activiti工作流项目

    【标题】"activiti工作流项目"是一个基于Java技术栈实现的工作流管理系统示例,它集成了SpringMVC、Hibernate和Activiti等关键组件。这个项目旨在演示如何在实际应用中利用Activiti来构建动态表单和处理各种流程审批...

    Activiti工作流使用手册操作文档

    Activiti工作流是一款开源的工作流程管理系统,主要用于企业的业务流程自动化。它基于模型驱动的设计理念,提供了丰富的API和图形化设计工具,使得开发者可以方便地创建、部署和管理工作流程。本操作手册旨在帮助...

    前后端分离项目中引入activiti工作流引擎

    ### 前后端分离项目中引入Activiti工作流引擎 #### 一、概述 在当前的软件开发中,前后端分离已经成为了一种常见的架构模式。这种模式将前端的用户界面与后端的数据处理逻辑分开,提高了开发效率,同时也使得系统...

    Activiti工作流示例Activiti Demo(带完整源码)非常实用

    这个"Activiti工作流示例Activiti Demo"提供了完整的源代码,帮助开发者深入理解并实际操作Activiti,从而更好地在自己的项目中应用。 在描述中提到的"Canvas动画"是指Activiti提供的可视化建模工具,它允许开发者...

    activiti工作流中文说明文档

    Activiti工作流中文说明文档 Activiti是一个基于Apache V2协议发布的开源工作流引擎,旨在帮助开发者快速构建业务流程管理系统。本文档将对Activiti的安装、配置、使用等方面进行详细介绍,以帮助开发者快速上手...

    activiti工作流案例

    Activiti工作流是一个开源的业务流程管理(BPM)和工作流引擎,它为企业提供了一种灵活、可扩展的方式来管理其业务流程。这个压缩包文件包含的“activiti工作流案例”是帮助初学者快速理解和实践Activiti工作流的一...

    activiti 工作流23张表详细介绍

    ### Activiti工作流23张表详细介绍 #### 一、Activiti数据库表结构概述 Activiti是一款开源的工作流引擎,其强大的流程管理能力使得它在众多业务场景中得到广泛应用。为了更好地理解Activiti如何存储流程数据,本...

    Activiti工作流引擎简介

    Activiti工作流引擎简介 1.俯瞰Activiti 2.Activiti开发之旅 3.Why Activiti? 4.Activiti的现状与未来

    Activiti工作流详细讲解完整教程.pdf

    根据提供的文件信息,我们可以深入探讨Activiti工作流框架的相关知识点。 ### Activiti工作流框架概述 Activiti工作流框架是一款由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架。它以其灵活性、易用...

    Activiti工作流黑马教程.doc

    activiti工作流视频课程文档,非常实用,activiti入门课程

    activiti工作流测试

    Activiti工作流测试是针对Activiti这一开源工作流引擎进行的一种实践操作,旨在帮助开发者理解和掌握如何在实际项目中运用Activiti。Activiti是一个轻量级、高效且灵活的业务流程管理(BPM)系统,它能够处理业务...

    Activiti工作流课程

    【Activiti工作流课程】深入解析 在信息技术领域,工作流(Workflow)是企业管理和自动化的重要工具,它使得复杂的业务过程能够在计算机环境中有序、高效地执行。工作流管理系统(Workflow Management System, WfMS...

    Activiti工作流HelloWorld入门

    Activiti工作流HelloWorld入门教程 Activiti是一款开源的工作流引擎,它基于Java技术,用于在企业级应用中实现业务流程自动化。这个“Activiti工作流HelloWorld入门”旨在帮助初学者快速理解并掌握Activiti的基本...

Global site tag (gtag.js) - Google Analytics