新发布的activiti5.16.4的modeler rest框架由Restlet改为Spring MVC,个人感觉和SSH项目集成更加方便,不用再引入一系列的Restlet相关jar包。
集成过程如下:
在maven pom.xml引入activiti依赖,其它项目运行需要的包根据需要添加。在引入org.activiti.activiti-modeler时,activiti-engine等包被一起引进来。activiti modeler直接需要的jar包为activiti-modeler.jar,其中包括rest地址的映射,内容很简单就几个类。
<properties> <activiti.version>5.16.4</activiti.version> </properties>
<dependency> <groupId>org.activiti</groupId> <artifactId>activiti-modeler</artifactId> <version>${activiti.version}</version> </dependency> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-explorer</artifactId> <version>${activiti.version}</version> <exclusions> <exclusion> <artifactId>vaadin</artifactId> <groupId>com.vaadin</groupId> </exclusion> <exclusion> <artifactId>dcharts-widget</artifactId> <groupId>org.vaadin.addons</groupId> </exclusion> <exclusion> <artifactId>activiti-simple-workflow</artifactId> <groupId>org.activiti</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-diagram-rest</artifactId> <version>${activiti.version}</version> </dependency>
activiti modeler使用的spring mvc,spring环境是必须的。在web.xml配置好spring和springmvc,参考如下,spring mvc默认拦截的所有的servlet请求。
<context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:/applicationContext.xml classpath*:/applicationContext-wf.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--字符编码过滤器 --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--引入spring mvc --> <servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-servlet.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
拷贝activiti modeler文件到指定目录,activiti modeler所需的文件都在activiti源码文件夹:modules\activiti-webapp-explorer2目录下。拷贝过程如下:将activiti-webapp-explorer2\src\main\resources下的stencilset.json、plugins.xml拷贝到项目的src\main\resources目录下;activiti-webapp-explorer2\src\main\resources下的editor.html拷贝到项目放web页面的目录下;activiti-webapp-explorer2\src\main\webapp下的aip、editor、explorer和libs文件夹拷贝到项目js资源目录下。
拷贝完成后目录结构如下图,我将editor.html改成了editor.jsp。
剩下的就配置spring mvc、activiti modeler服务和资源的请求地址了。spring mvc配置,在spring mvc配置文件中加入要扫描的activiti modeler需要的rest服务类包,如下。
<!-- activiti modeler rest服务,位于activiti-modeler.jar下 --> <context:component-scan base-package="org.activiti.rest.editor"></context:component-scan>
spring mvc视图解析器的页面的根目录设置为/WEB-INF/views。
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp"></property> </bean>
在spring配置文件中,添加ObjectMapper的bean,activiti modeler在进行json转换时会用到。
<!-- json处理 --> <bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"></bean>
在spring中配置activiti,提供activiti各种服务端的bean。
更改oryx.debug.js中对activiti modeler服务和资源地址的引用。虽然在oryx中声明了配置的公共地址,但是在js文件中多处仍是写死的,附件oryx.debug.js规范对服务和资源的地址引用,下载后需要按照如下修改。
修改editor中js和css文件引用的路径,如下图。
提供创建Model和跳转editor.jsp页面的rest服务,如下。
@RequestMapping("wf")
@Controller
public class WFController {
@Autowired
private TaskService taskService ;
@Autowired
private RuntimeService runtimeService ;
@Autowired
private RepositoryService repositoryService ;
@Autowired
private ObjectMapper objectMapper ;
/**
* 通过spring mvc 的rest地址打开bpmn编辑器
* @return
*/
@RequestMapping("editor")
public ModelAndView getEditor(){
ModelAndView modelAndView = new ModelAndView("wfmodeler/editor") ;
return modelAndView ;
}
/**
* 新建一个模型,返回新建模型的id
* @return
* @throws UnsupportedEncodingException
*/
@RequestMapping("newmodeler")
@ResponseBody
public String createNewModeler() throws UnsupportedEncodingException{
//删除已有的流程模型
// List<Model> models = repositoryService.createModelQuery().modelNameLike("%new design model%").list() ;
// for (Model oldModel : models) {
// repositoryService.deleteModel(oldModel.getId());
// }
//新建模型
Model model = repositoryService.newModel() ;
model.setName("new design model");
model.setCategory("namespace");
model.setKey("form design key");
model.setTenantId(Constants.DEFAULT_TENANT);
model.setVersion(1);
ObjectNode metaNode = objectMapper.createObjectNode();
metaNode.put(ModelDataJsonConstants.MODEL_NAME, "new modeler");
metaNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
metaNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, "no formal data");
model.setMetaInfo(metaNode.toString());
//保存模型
repositoryService.saveModel(model);
//为模型生成一个空的wf模型
ObjectNode editorNode = new ObjectMapper().createObjectNode();
//id和resource可以没有
editorNode.put("id", "canvas");
editorNode.put("resourceId", "canvas");
ObjectNode stencilSetNode = objectMapper.createObjectNode();
//namespace的值和stencilset.json中namespace的值相同,
stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
editorNode.put("stencilset", stencilSetNode);
//只添加bpmn的json数据即可
repositoryService.addModelEditorSource(model.getId(), editorNode.toString().getBytes(Constants.CHARSET_UTF_8));
return model.getId() ;
}
}
按照如上配置,通过访问http://ip:port/projects-formdesigner/wf/editor/?id=19601就可以跳转到模型编辑页面。