在struts2项目中集成Activiti-Modeler5.19

一.缘由

最近公司让做一个工作流的项目,之前也没接触过,网上也没什么资料,偶然在github上发现了一个咖啡兔的Activiti-demo,打断点跟着看终于明白了一点,自己搭建了一个Spring MVC + Spring + Mybatis的环境也做了一个demo.
但是部署到公司机器上才发现,公司用的是struts2,与Spring MVC还是有点不同的,然后就是漫长的修改代码,中间就发生了一些问题

二.具体问题

在Spring MVC中所有功能都能正常使用,但是移植到struts2时,每次访问在线流程绘制时就会报错,访问localhost:8080/Activiti-demo/service/项目就会重启,貌似由于资源未释放,最后报的是OutOfMemoryError Permgen Space
activiti-modeler的服务配置在web.xml

  <!-- Modeler的Rest服务 -->
  <servlet>
    <servlet-name>ModelRestServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc-modeler.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>ModelRestServlet</servlet-name>
    <url-pattern>/service/*</url-pattern>
  </servlet-mapping>

几番查找终于发现是ModelerRest服务出错,首先看看spring-mvc-modeler.xml,核心如下

<!-- 自动扫描且只扫描@Controller -->
<context:component-scan base-package="org.activiti.rest.editor">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

<mvc:annotation-driven />

继续追溯org.activiti.rest.editor,即是Activiti-modeler-5.19.0.jar,这个jar包的结构如下图:
Activiti-Modeler-5.19.0.jar

其中,StencilsetRestResource类顾名思义,是加载模板设置,加载resources下的stencilset.json,其代码如下:
StencilsetRestResource

ModelEditorJsonRestResource类是根据模型名称读取以Json存储在act_ge_bytearray表中的source,编辑器接收到之后解析展示为图片,其核心代码如下:
ModelEditorJsonRestResource

ModelSaveRestResource就是将经过编辑器编辑过的模型保存起来,核心代码如下:
ModelSaveRestResource

三.解决办法

总结一下,Activiti-Modeler主要做了三件事,加载模板,加载模型,保存模型,url分别为
service/editor/stencilset,
service/model/{modelId}/json,
service/model/{modelId}/save
而这三个类使用的都是Spring MVC的注解,所以想要在struts2中使用,可以自己重写这三个类
但是重写之后url怎么解决呢?毕竟struts2没有@PathVariable注解.
找了半天终于在editor-app下找到了,路径为

editor-app/configuration/url-config.js

url-config.js

可以在这里修改url,这样就不需要在web.xml中配置servlet了
editor-app还有一个设置,路径是editor-app/app-cfg.js

扫描二维码关注公众号,回复: 2890550 查看本文章
'use strict';

var ACTIVITI = ACTIVITI || {};

ACTIVITI.CONFIG = {
    'contextRoot' : '/Activiti-demo/service',
};

在这里可以配置modeler的访问路径前缀

说了这么多我自己还没实践呢,明天去公司做完再来补充

四.补充(2015.12.25夜)

1.StencilsetRestResource加载stencilset.json

比较简单,不说了

2.ModelEditorJsonRestResource取得json格式的模型数据

这个也比较简单,唯一要注意的就是返回的是json,最后直接modelNode.toString()输出json格式数据即可.

3.ModelSaveRestResource保存模型数据

这个真是坑爹啊

首先这个方法接收的参数,我们可以通过查看编辑器保存的方法来看传递的参数,路径是editor-app/configuration/toolbar-default-action.js:
编辑器保存的方法

这里第一个参数包含四个部分,name模型名称,description模型描述,json_xml模型数据,svg_xml模型图像,但是它是PUT过来的,无法通过name来获取,只能以流的形式读取出来,然后进行解析,Spring MVC自带@RequestBody实在是很方便.

第二个参数在url里传递,这里上面已经说过,自定义url里传递modelId

那么我们既然没有@RequestBody注解来像原先那样快速解析,只能自己手动解析了,下面只从方法概述,不涉及具体代码.

解码之后的数据格式:json_xml={xxxx}&svg_xml={xxx}&name=xxxx&description=xxxx

1.从request中以流的形式读取出数据,这里得到的数据是经过url编码的数据
2.这里先不急着解码,先将数据按照’&’分隔开,可以使用spilt(),得到一个数组
3.遍历这个数组,按照’=’将字符串切割开,将索引0和索引1的值解码,并放到一个map里面,解码参照URL编码解码

这样我们就得到了一个map,例如直接使用map.get(“name”)就能取得name对应的值,这样稍微修改一下源码就能实现模型的保存了

4.url

前面说了通过修改url-config.js就能实现自定义url,但是在使用过程中还是发现请求stencilset.json是还是使用的原先的url,找了半天终于找到了原因

editor-app/editor/oryx.debug.js
8190行有个bug如图

oryx.debug.js

这里没有使用url-config.js里面预先定义的url,所以如果你修改了url,必须在这里进行同步修改

干脆将8090-8195行修改为如下,即可一劳永逸解决问题

new Ajax.Request(KISBPM.URL.getStencilSet(), {
    asynchronous: false,
    method: 'get',
    onSuccess: this._init.bind(this),
    onFailure: this._cancelInit.bind(this)
});

猜你喜欢

转载自blog.csdn.net/Amayadream/article/details/50390168