Springboot2.0與activiti-explorer5.23.0整合,從0開始構建自己的工作流編輯平臺(附件 漢化版)
一、構建使用Idea構建Springboot項目
a)利用IDEA構架Maven工程
操作步驟:File-Project-New Project。
b) Spring Initailer嚮導構建Maven工程
c)點擊"Next",進入項目配置界面
d) 項目會使用到 Spring Web,MyBatis, MySql,勾選這三項即可
e) 配置項目名稱和目錄點擊 "Finish"完成創建
二、加入Activiti Explorer相關的Maven依賴
a) 項目創建成功後,加入版本activiti的版本號
截止到文章編寫時,activiti-explorer的最新版本爲5.23.0,所以此處使用activiti的版本也爲5.23.0
<activiti.version>5.23.0</activiti.version>
<activiti.diagram.version>5.23.0</activiti.diagram.version>
b) 加入Activiti依賴的maven文件
<!--activiti 依賴開始-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-actuator</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-rest</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-explorer</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-diagram-rest</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-modeler</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-simple-workflow</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-codec</artifactId>
<version>${batik.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-css</artifactId>
<version>${batik.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-svg-dom</artifactId>
<version>${batik.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-svggen</artifactId>
<version>${batik.version}</version>
</dependency>
<!--activiti 依賴結束-->
c) 配置application.yml文件
在application.yml中加入mysql數據庫連接配置,Mybatis配置和activiti的連接配置。
注意:
&nullCatalogMeansCurrent=true,如果是mysql-connector-java版本爲5.x以上的版本需要加入此配置。不然會導致sql執行失敗的問題。
nullCatalogMeansCurrent
-
從mysql-connector-java 5.x 到 6.x,nullCatalogMeansCurrent屬性由原來的默認true改爲了false。
-
true 使用指定的數據庫進行查詢。優先取當前傳入的數據庫名,其次取當前鏈接的數據庫名。
-
false 代表遍歷當前鏈接下的所有數據庫進行查詢,就是遍歷當前鏈接下的所有數據庫(information_schema, mysql 和 performance_schema 這三個系統DB,雖然在最終結果裏進行了排除,但是依然進行了查詢。
此處默認生成的是8.0.20,所以連接的URL中需要加入此屬性
application.yml配置
spring:
application:
name: springboot-activiti-explorer
# 數據源
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
hikari:
minimum-idle: 2
maximum-pool-size: 5
#html靜態頁面路徑
resources:
static-locations: classpath:static/,file:static/
#activiti
#表示啓動時檢查數據庫表,不存在則創建
activiti:
database-schema-update: true
#表示哪種情況下使用歷史表,這裏配置爲full表示全部記錄歷史,方便繪製流程圖
history-level: full
#true表示使用歷史表,如果不配置,則工程啓動後可以檢查數據庫,只建立了17張表
db-history-used: true
#校驗流程定義規範
check-process-definitions: false
mybatis:
mapper-locations: classpath:mapping/*Mapper.xml
type-aliases-package: hu.itget.entity
d) 執行Springboot的Application的main方法,冒煙啓動
翻車,啓動失敗!
錯誤日誌
(此處省略)
......
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.0.RELEASE)
2020-06-11 22:44:38.711 INFO 29220 --- [ main] .a.SpringbootActivitiExplorerApplication : Starting SpringbootActivitiExplorerApplication on huyiqing with PID 29220 (D:\ITGET\idea_itget_work\springboot-activiti-explorer\target\classes started by 胡 in D:\ITGET\idea_itget_work\springboot-activiti-explorer)
2020-06-11 22:44:38.715 INFO 29220 --- [ main] .a.SpringbootActivitiExplorerApplication : No active profile set, falling back to default profiles: default
2020-06-11 22:44:39.248 WARN 29220 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [hu.itget.io.activiti.SpringbootActivitiExplorerApplication]; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/authentication/configurers/GlobalAuthenticationConfigurerAdapter.class] cannot be opened because it does not exist
2020-06-11 22:44:39.254 INFO 29220 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-06-11 22:44:39.266 ERROR 29220 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [hu.itget.io.activiti.SpringbootActivitiExplorerApplication]; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/authentication/configurers/GlobalAuthenticationConfigurerAdapter.class] cannot be opened because it does not exist
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:609) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.access$800(ConfigurationClassParser.java:110) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.lambda$processGroupImports$1(ConfigurationClassParser.java:811) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at java.util.ArrayList.forEach(ArrayList.java:1257) ~[na:1.8.0_211]
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:808) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:779) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:192) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:319) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:280) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:96) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at hu.itget.io.activiti.SpringbootActivitiExplorerApplication.main(SpringbootActivitiExplorerApplication.java:10) [classes/:na]
Caused by: java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/authentication/configurers/GlobalAuthenticationConfigurerAdapter.class] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180) ~[spring-core-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.core.type.classreading.SimpleMetadataReader.getClassReader(SimpleMetadataReader.java:55) ~[spring-core-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:49) ~[spring-core-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103) ~[spring-core-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:86) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:73) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81) ~[spring-core-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:695) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getSuperClass(ConfigurationClassParser.java:1009) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:340) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:249) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processMemberClasses(ConfigurationClassParser.java:371) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:271) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:249) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:599) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 20 common frames omitted
Disconnected from the target VM, address: 'javadebug', transport: 'shared memory'
Process finished with exit code 1
e)解決SecurityAutoConfiguration和SecurityAutoConfiguration安全檢查
此處移除security安全校驗方法爲修改Application啓動類。
@SpringBootApplication(exclude = { org.activiti.spring.boot.SecurityAutoConfiguration.class,
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class })
f) 加入完成後再次啓動,啓動成功
到此步,Springboot後端的配置成功。下面處理前端頁面。
三、配置activiti-explorer在線設計器
a) 下載 activiti-webapp-explorer2-5.23.0.war
使用壓縮工具解壓,如圖:
b) 將diagram-viewer,editor-app,modeler.html三個文件複製到springboot的項目
在Springboot的項目的resource目錄的static文件夾下新建一個activiti-explorer文件夾。(此處根據自己要求是否新建文件夾)
複製完成後如下:
c) 複製配置文件stencilset.json到Springboo項目
stencilset.json在activiti-webapp-explorer2-5.23.0.war的文件夾下路徑:
activiti-webapp-explorer2-5.23.0\WEB-INF\classes
將stencilset.json文件複製到 項目工程的 resource目錄下,給前臺頁面提供報文。
d) 修改StencilsetRestResource, ModelEditorJsonRestResource,ModelSaveRestResource請求接口路徑
Js的文件路徑爲:
src\main\resources\static\activiti-explorer\editor-app\app-cfg.js
刪除activiti-explorer/service 修改後的值爲:
接口文件在activiti-modeler.jar中
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-modeler</artifactId>
<version>${activiti.version}</version>
</dependency>
e) 項目啓動完成,輸入URL測試項目啓動是否成功
http://localhost:8080/activiti-explorer/modeler.html?modelId=1
按F12查看控制檯,出現如下異常:
經過排插是創建模型時缺少初始化數據,是因爲我們的modelId=1是亂輸入的,應該要和數據庫表ACT_RE_MODEL對應起來。
於是手動編寫一個初始化模型數據類如下:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
@Controller
@RequestMapping("/models")
public class TestActivitiController {
private static final Logger LOGGER = LoggerFactory.getLogger(TestActivitiController.class);
@Autowired
private RepositoryService repositoryService;
@Autowired
private ObjectMapper objectMapper;
@RequestMapping("/create")
public void newModel(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
try {
// 初始化一個空模型
Model model = repositoryService.newModel();
// 設置一些默認信息
String name = "new-process";
String description = "";
int revision = 1;
String key = "process";
ObjectNode modelNode = objectMapper.createObjectNode();
modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision);
model.setName(name);
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);
repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));
response.sendRedirect(request.getContextPath() + "/static/modeler.html?modelId=" + id);
} catch (IOException e) {
e.printStackTrace();
LOGGER.info("模型創建失敗!");
}
}
}
同時加上Bean的掃描路徑註解:
@SpringBootApplication(scanBasePackages = { "org.activiti.rest", "hu.itget" }, exclude = {
org.activiti.spring.boot.SecurityAutoConfiguration.class,
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class })
f) 解決問題,再次測試。
啓動完成後,輸入URL
http://localhost:8080/models/create
URL重定向到
http://localhost:8080/activiti-explorer/modeler.html?modelId=2501
到此配置完成。可以實現項目中整合自己帶activiti在線編輯頁面。
另外如果需要 activiti-explorer-5.23.0 漢化版的小夥伴可以如下鏈接下載:
關注公衆號 回覆
5.23.0
即可獲取下載地址。
參考文檔
https://www.cnblogs.com/zhouyun-yx/p/10410274.html