Spring Boot集成Activiti —— 流程编辑器集成

项目说明

该项目综合参考了:chenhai201 和 secsea

在进行下面的项目实践时,请先生成一个spring boot项目,并配置swagger2,开发工具建议使用IDEA。为了方便正文的描述,下面先给出项目的整体目录结构。

Spring Boot集成Activiti —— 流程编辑器集成_第1张图片

项目已经上传到github,需要可以自行下载

Activitig下载

首先从github上下载Activiti的源码,命令如下

git clone https://github.com/Activiti/Activiti.git
git checkout 5.23.0-release

项目依赖

在项目中加上对activiti的依赖,整体项目pom如下所示



    4.0.0

    
        org.springframework.boot
        spring-boot-starter-parent
        1.5.4.RELEASE
         
    

    org.self
    activitidemo
    0.0.1-SNAPSHOT
    activitidemo
    Demo project for Spring Boot Activiti

    
        UTF-8
        UTF-8
        1.8
        5.22.0
        2.6.1
    

    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            
            
        

        
            org.springframework.boot
            spring-boot-starter-data-jpa
        

        
            net.sourceforge.nekohtml
            nekohtml
            1.9.22
        

        
            org.activiti
            activiti-spring-boot-starter-basic
            ${activiti.version}
        
        
            org.activiti
            activiti-spring-boot-starter-actuator
            ${activiti.version}
        
        
            org.activiti
            activiti-rest
            ${activiti.version}
        

        
            org.apache.xmlgraphics
            batik-codec
            1.7
        
        
            org.apache.xmlgraphics
            batik-css
            1.7
        
        
            org.apache.xmlgraphics
            batik-svg-dom
            1.7
        
        
            org.apache.xmlgraphics
            batik-svggen
            1.7
        
        
            org.activiti
            activiti-explorer
            ${activiti.version}
        
        
            org.activiti
            activiti-diagram-rest
            ${activiti.version}
        
        
            org.activiti
            activiti-simple-workflow
            ${activiti.version}
        
        
            org.activiti
            activiti-spring
            ${activiti.version}
        

        
            mysql
            mysql-connector-java
            
            
            runtime
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
        
            io.springfox
            springfox-swagger2
            ${swagger.version}
        
        
            io.springfox
            springfox-swagger-ui
            ${swagger.version}
        

        
            io.jsonwebtoken
            jjwt
            0.7.0
        

    

    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Dalston.SR1
                pom
                import
            
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

整合编辑器代码

1)在org.self.activitidemo.config包下建立activiti.modeler.exploer包,然后在下载的Activiti源码中,找到目录modules\activiti-webapp-explorer2\src\main\java\org\activiti\explorer\servlet,然后复制FilterServletOutputStream.java、GenericResponseWrapper.java、JsonpCallbackFilter.java到上面建立的activiti.modeler.exploer包下,如下所示

Spring Boot集成Activiti —— 流程编辑器集成_第2张图片

2)从目录modules\activiti-webapp-explorer2中复制src\main\resources路径下的stencilset.json文件到本地项目的resources目录下

3)从目录modules\activiti-webapp-explorer2中复制src\main\webapp路径下的文件diagram-viewer和editor-app目录,以及modeler.html文件

4)从目录modules\activiti-webapp-explorer2中复制src\main\java\org\activiti\reset\editor路径下的文件main和model到controller下的editor包

如下所示:

Spring Boot集成Activiti —— 流程编辑器集成_第3张图片

修改及扩展代码

1)找到controller.editor.main和controller.editor.model中的StencilsetRestResource.java、ModelEditorJsonRestResource.java、ModelSaveRestResource.java,统一在类上加

@RequestMapping(value = "/service")

2)在Spring boot的启动类ActivitidemoApplication,加上如下注解【ComponentScan里面的第二个包记得换成自己的包】

@ComponentScan({"org.activiti.rest.diagram", "org.self.activitidemo"})
@EnableAutoConfiguration(exclude = {
		org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class,
		org.activiti.spring.boot.SecurityAutoConfiguration.class,
		org.springframework.boot.actuate.autoconfigure.ManagementWebSecurityAutoConfiguration.class
})

并在启动类中加上Bean,如下

@Bean
public JsonpCallbackFilter filter(){
    return new JsonpCallbackFilter();
}

3)修改resource/static/editor-app下的app-cfg.js为

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

4)在constant包下,添加两个辅助类Pagination.java和ResponseConstantManager.java

package org.self.activitidemo.constant;

import java.util.List;

/**
 * 分页类
 */
public class Pagination {

    public static int DEFAULT_PAGENUMBER = 1;
    public static int DEFAULT_PAGESIZE = 10;

    private List rows = null; //当前返回的记录列表
    private int rowTotal = 0; //总记录数
    private int pageTotal = 0; //总页数


    protected int pageNumber = DEFAULT_PAGENUMBER;  //页码
    protected int pageSize = DEFAULT_PAGESIZE; //每页记录数

    public Pagination() {
        this(DEFAULT_PAGENUMBER, DEFAULT_PAGESIZE);
    }

    public Pagination(int pageNumber, int pageSize) {
        setPageNumber(pageNumber);//pageNumber从1开始不是从0开始
        setPageSize(pageSize);
    }

    public static Pagination getInstance(int pageNumber, int pageSize) {
        return new Pagination(pageNumber, pageSize);
    }

    public static Pagination getInstance2Top(int top) {
        return new Pagination(1, top);
    }

    public List getRows() {
        return rows;
    }

    public void setRows(List rows) {
        this.rows = rows;
    }

    public int getRowTotal() {
        return rowTotal;
    }

    public void setRowTotal(int rowTotal) {
        this.rowTotal = rowTotal;
    }

    public int getPageTotal() {
        return pageTotal;
    }

    public void setPageTotal(int pageTotal) {
        this.pageTotal = pageTotal;
    }

    public int getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(int pageNumber) {
        this.pageNumber = pageNumber;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getStart(){
        return (getPageNumber()-1)*getPageSize();
    }
    public int getEnd(){
        return getStart() + getPageSize();
    }
}
package org.self.activitidemo.constant;

/**
 * 用于维护响应需要的常量信息
 */
public class ResponseConstantManager {
    public static final String STATUS_SUCCESS = "success";
    public static final String STATUS_FAIL = "fail";

}

在service包下,加入ModelServer.java接口类,建立service.impl包,在service.impl下加入ModelServiceImpl.java,如下

package org.self.activitidemo.service;

import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;

/** 流程模型管理的接口 */
public interface ModelService {
    /** 新建一个模型 */
    HashMap newModel(String modelName, String description, String key);

    /** 获取所有模型 */
    HashMap modelList();

    /** 获取指定页码的模型 */
    HashMap modelsPage(int pageSize, int pageNumber);

    /** 删除指定模型 */
    HashMap deleteModel(String modelId);

    /** 部署模型 */
    HashMap deployModel(String modelId);

    /** 上传已有xml文件,并生成相应模型*/
    HashMap uploadModel(MultipartFile modelFile);



}
package org.self.activitidemo.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.Model;
import org.activiti.explorer.util.XmlUtil;
import org.apache.commons.lang3.StringUtils;
import org.self.activitidemo.constant.Pagination;
import org.self.activitidemo.constant.ResponseConstantManager;
import org.self.activitidemo.service.ModelService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;

@Service
public class ModelServiceImpl implements ModelService {
    private static final Logger logger = LoggerFactory.getLogger(ModelServiceImpl.class);

    @Autowired
    RepositoryService repositoryService;

    @Autowired
    ObjectMapper objectMapper;

    @Override
    public HashMap newModel(String modelName, String description, String key) {
        HashMap result = new HashMap<>();

        //初始化一个空模型
        Model model = repositoryService.newModel();

        //int revision = 1;

        ObjectNode modelNode = objectMapper.createObjectNode();
        modelNode.put(ModelDataJsonConstants.MODEL_NAME, modelName);
        modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
//        modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision);

        model.setName(modelName);
        model.setKey(key);
        model.setMetaInfo(modelNode.toString());

        repositoryService.saveModel(model);
        String id = model.getId();

        //完善ModelEditorSource
        ObjectNode editorNode = objectMapper.createObjectNode();
        editorNode.put("id", "canvas");
        editorNode.put("resourceId", "canvas");
        ObjectNode stencilSetNode = objectMapper.createObjectNode();
        stencilSetNode.put("namespace",
                "http://b3mn.org/stencilset/bpmn2.0#");
        editorNode.put("stencilset", stencilSetNode);
        try {
            repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));
            result.put("status", ResponseConstantManager.STATUS_SUCCESS);
            result.put("modelId", id);
        } catch (UnsupportedEncodingException e) {
            result.put("status", ResponseConstantManager.STATUS_FAIL);
            result.put("message", e.toString());
        }
        return result;
    }

    @Override
    public HashMap modelList() {
        HashMap result = new HashMap<>();
        List models = repositoryService.createModelQuery().orderByCreateTime().asc().list();
        result.put("status", ResponseConstantManager.STATUS_SUCCESS);
        result.put("models", models);
        return result;
    }

    @Override
    public HashMap modelsPage(int pageNumber, int pageSize) {
        HashMap result = new HashMap<>();

        Pagination pagination = new Pagination(pageNumber, pageSize);
        int totalCount = (int) repositoryService.createModelQuery().count();
        int totalPages = (int) Math.ceil(totalCount / pageSize);
        pagination.setRowTotal(totalCount);
        pagination.setPageTotal(totalPages);

        List models = repositoryService.createModelQuery()
                .orderByCreateTime().asc().listPage(pagination.getStart(), pagination.getEnd());
        pagination.setRows(models);
        result.put("status", ResponseConstantManager.STATUS_SUCCESS);
        result.put("modelsPage", pagination);
        return result;
    }

    @Override
    public HashMap deleteModel(String modelId) {
        HashMap result = new HashMap<>();
        repositoryService.deleteModel(modelId);
        result.put("status", ResponseConstantManager.STATUS_SUCCESS);
        return result;
    }

    @Override
    public HashMap deployModel(String modelId) {
        HashMap result = new HashMap<>();

        //获取模型
        Model modelData = repositoryService.getModel(modelId);
        byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());

        if (bytes == null) {
            result.put("status", ResponseConstantManager.STATUS_FAIL);
            result.put("message", "模型数据为空,请先设计流程并成功保存,再进行发布。");
            return result;
        }
        try {
            JsonNode modelNode = new ObjectMapper().readTree(bytes);

            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            if (model.getProcesses().size() == 0) {
                result.put("status", ResponseConstantManager.STATUS_FAIL);
                result.put("message", "数据模型不符要求,请至少设计一条主线流程。");
            }
            //debug
            byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);
//            System.out.println(new String(bpmnBytes, "UTF-8"));

            //发布流程
            String processName = modelData.getName() + ".bpmn20.xml";
//            DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
//                    .name(modelData.getName())
//                    .addString(processName, new String(bpmnBytes, "UTF-8"));
            DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
                    .name(modelData.getName())
                    .addBpmnModel(processName, model);

            Deployment deployment = deploymentBuilder.deploy();
            modelData.setDeploymentId(deployment.getId());
            repositoryService.saveModel(modelData);
        } catch (Exception e) {
            result.put("status", ResponseConstantManager.STATUS_FAIL);
            result.put("message", e.toString());
        }
        return result;
    }

    @Override
    public HashMap uploadModel(MultipartFile modelFile) {
        HashMap result = new HashMap<>();
        InputStreamReader in = null;
        try {
            try {
                boolean validFile = false;
                String fileName = modelFile.getOriginalFilename();
                if (fileName.endsWith(".bpmn20.xml") || fileName.endsWith(".bpmn")) {
                    validFile = true;
                    XMLInputFactory xif = XmlUtil.createSafeXmlInputFactory();
                    in = new InputStreamReader(new ByteArrayInputStream(modelFile.getBytes()), "UTF-8");
                    XMLStreamReader xtr = xif.createXMLStreamReader(in);
                    BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);

                    if (bpmnModel.getMainProcess() == null || bpmnModel.getMainProcess().getId() == null) {
//                        notificationManager.showErrorNotification(Messages.MODEL_IMPORT_FAILED,
//                                i18nManager.getMessage(Messages.MODEL_IMPORT_INVALID_BPMN_EXPLANATION));
                        result.put("status", ResponseConstantManager.STATUS_FAIL);
                        result.put("message", "数据模型无效,必须有一条主流程");
                    } else {
                        if (bpmnModel.getLocationMap().isEmpty()) {
//                            notificationManager.showErrorNotification(Messages.MODEL_IMPORT_INVALID_BPMNDI,
//                                    i18nManager.getMessage(Messages.MODEL_IMPORT_INVALID_BPMNDI_EXPLANATION));
                            result.put("status", ResponseConstantManager.STATUS_FAIL);
                            result.put("message", "locationMap为空");
                        } else {
                            String processName = null;
                            if (StringUtils.isNotEmpty(bpmnModel.getMainProcess().getName())) {
                                processName = bpmnModel.getMainProcess().getName();
                            } else {
                                processName = bpmnModel.getMainProcess().getId();
                            }
                            Model modelData;
                            modelData = repositoryService.newModel();
                            ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
                            modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processName);
                            modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
                            modelData.setMetaInfo(modelObjectNode.toString());
                            modelData.setName(processName);

                            repositoryService.saveModel(modelData);

                            BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
                            ObjectNode editorNode = jsonConverter.convertToJson(bpmnModel);

                            byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(bpmnModel);
//                            System.out.println(new String(bpmnBytes, "UTF-8"));
//                            System.out.println(editorNode);

                            repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));
                            result.put("status", ResponseConstantManager.STATUS_SUCCESS);
                            result.put("modelId", modelData.getId());
                        }
                    }
                } else {
//                    notificationManager.showErrorNotification(Messages.MODEL_IMPORT_INVALID_FILE,
//                            i18nManager.getMessage(Messages.MODEL_IMPORT_INVALID_FILE_EXPLANATION));
                    result.put("status", ResponseConstantManager.STATUS_FAIL);
                    result.put("message", "后缀名无效");
                    System.out.println("err3");
                }
            } catch (Exception e) {
//                String errorMsg = e.getMessage().replace(System.getProperty("line.separator"), "
"); // notificationManager.showErrorNotification(Messages.MODEL_IMPORT_FAILED, errorMsg); result.put("status", ResponseConstantManager.STATUS_FAIL); result.put("message", e.toString()); } } finally { if (in != null) { try { in.close(); } catch (IOException e) { // notificationManager.showErrorNotification("Server-side error", e.getMessage()); result.put("status", ResponseConstantManager.STATUS_FAIL); result.put("message", e.toString()); } } } return result; } }

在controlle.clientr包下,加入 ModelController.java,代码如下:

package org.self.activitidemo.controller.client;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.self.activitidemo.service.ModelService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;

/**
 * 流程模型Model操作相关
 * Created by chenhai on 2017/5/23.
 */
@Api(description = "流程模型Model操作相关", tags = {"activitimodeler"})
@RestController
@RequestMapping("models")
public class ModelController {
    private  final static Logger logger = LoggerFactory.getLogger(ModelController.class);

    @Autowired
    private ModelService modelService;

    /**
     * 新建一个空模型
     *
     * @return
     * @throws UnsupportedEncodingException
     */
    @ApiOperation(value = "新建一个空模型")
    @PostMapping(value = "newModel")
    public ResponseEntity newModel(@RequestParam(value = "modelName") String modelName,
                                   @RequestParam(value = "description") String description,
                                   @RequestParam(value = "key") String key) throws UnsupportedEncodingException {

        HashMap responseBody = modelService.newModel(modelName, description, key);
        return ResponseEntity.status(HttpStatus.OK).body(responseBody);
    }

    /**
     * 获取所有模型
     *
     * @return
     */
    @ApiOperation(value = "获取所有模型")
    @GetMapping("/getAll")
    public ResponseEntity modelList() {
        HashMap responseBody = modelService.modelList();
        return ResponseEntity.status(HttpStatus.OK).body(responseBody);
    }

    /**
     * 删除模型
     *
     * @param modelId
     * @return
     */
    @ApiOperation(value = "删除模型")
    @DeleteMapping("delete/{modelId}")
    public ResponseEntity deleteModel(@PathVariable("modelId") String modelId) {
        HashMap responseBody = modelService.deleteModel(modelId);
        return ResponseEntity.status(HttpStatus.OK).body(responseBody);
    }

    /**
     * 发布模型为流程定义
     *
     * @param modelId
     * @return
     */
    @ApiOperation(value = "发布模型为流程定义")
    @PostMapping("deploy/{modelId}")
    public ResponseEntity deploy(@PathVariable("modelId") String modelId) {
        HashMap responseBody = modelService.deployModel(modelId);
        return ResponseEntity.status(HttpStatus.OK).body(responseBody);
    }

    @ApiOperation(value = "上传一个已有模型")
    @PostMapping(value = "/uploadFile")
    public ResponseEntity deployUploadedFile(@RequestParam("modelFile") MultipartFile modelFile) {
        HashMap responseBody = modelService.uploadModel(modelFile);
        return ResponseEntity.status(HttpStatus.OK).body(responseBody);
    }
}

5)修改controller.editor.model.ModelSaveRestResource.java,如下

@RestController
@RequestMapping(value = "/service")
public class ModelSaveRestResource implements ModelDataJsonConstants {

  protected static final Logger LOGGER = LoggerFactory.getLogger(ModelSaveRestResource.class);

  @Autowired
  private RepositoryService repositoryService;

  @Autowired
  private ObjectMapper objectMapper;

  @RequestMapping(value="/model/{modelId}/save", method = RequestMethod.PUT)
  @ResponseStatus(value = HttpStatus.OK)
  public void saveModel(@PathVariable String modelId, @RequestParam("name") String name,
                        @RequestParam("json_xml") String json_xml, @RequestParam("svg_xml") String svg_xml,
                        @RequestParam("description") String description) {//对接收参数进行了修改
    try {

      Model model = repositoryService.getModel(modelId);

      ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo());

      modelJson.put(MODEL_NAME, name);
      modelJson.put(MODEL_DESCRIPTION, description);
      model.setMetaInfo(modelJson.toString());
      model.setName(name);

      repositoryService.saveModel(model);

      repositoryService.addModelEditorSource(model.getId(), json_xml.getBytes("utf-8"));

      InputStream svgStream = new ByteArrayInputStream(svg_xml.getBytes("utf-8"));
      TranscoderInput input = new TranscoderInput(svgStream);

      PNGTranscoder transcoder = new PNGTranscoder();
      // Setup output
      ByteArrayOutputStream outStream = new ByteArrayOutputStream();
      TranscoderOutput output = new TranscoderOutput(outStream);

      // Do the transformation
      transcoder.transcode(input, output);
      final byte[] result = outStream.toByteArray();
      repositoryService.addModelEditorSourceExtra(model.getId(), result);
      outStream.close();

    } catch (Exception e) {
      LOGGER.error("Error saving model", e);
      throw new ActivitiException("Error saving model", e);
    }
  }
}

上面 操作之后整体目录结构如下所示:

Spring Boot集成Activiti —— 流程编辑器集成_第4张图片

6)进行数据库配置

先进行配置文件application.properties,内容如下

spring.application.name=activitidemo
server.port=8082

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://XXXX:3306/activiti_demo?ccharacterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=XXX
spring.datasource.password=XXX

spring.jpa.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.show-sql=true

#关闭activiti的自动部署机制
spring.activiti.check-process-definitions=false

从上述的项目github地址中,下载db下的sql文件,并运行生成activiti的数据库表

测试

运行Spring Boot项目,访问http://localhost:8082/swagger-ui.html,界面图如下所示:

Spring Boot集成Activiti —— 流程编辑器集成_第5张图片

点击newModel,填充参数,生成一个新的模型图,获取模型编号,如下

Spring Boot集成Activiti —— 流程编辑器集成_第6张图片

访问地址:http://localhost:8082/modeler.html?modelId=297501

界面如下

Spring Boot集成Activiti —— 流程编辑器集成_第7张图片

随便编辑,然后保存

自定义编辑器访问地址

加入thymeleaf依赖

        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        

加入application.properties配置

#thymeleaf
spring.mvc.view.prefix=classpath:/templates
spring.mvc.view.suffix=.html
#spring.thymeleaf.prefix=classpath:/templates
spring.thymeleaf.mode=LEGACYHTML5
#spring.thymeleaf.cache=false

在resources加入templates目录,同时加入modeler.html文件

!doctype html>




 

    
    
    Activiti Editor
    
    
    

    
    

    
    

	
    




	
	
	
	
	
{ {alerts.current.message}}
{ {alerts.queue.length + 1}}

在controller.client下加入EditorController.java

package org.self.activitidemo.controller.client;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;


//这里要使用Controller,因为RestController是返回json数据的
@Api(tags = "EditorController", description = "模型编辑器")
@Controller
public class EditorController {
    /**
     * 等同于访问:modeler.html?modelId=300001,这个是静态资源直接访问
     * @return
     */
    @ApiOperation(value = "进入流程编辑器,需要接入模型参数,editor?modelId=XXX")
    @GetMapping(value = "editor")
    public String edtior() {
        return "modeler";
    }
}

访问http://localhost:8082/editor?modelId=297501

 

你可能感兴趣的:(java,web后台,activiti流程编辑器,spring,boot,activiti)