新发布的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就可以跳转到模型编辑页面。