操作步骤:File-Project-New Project。
截止到文章编写时,activiti-explorer的最新版本为5.23.0,所以此处使用activiti的版本也为5.23.0
5.23.0
5.23.0
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.activiti
activiti-explorer
${activiti.version}
org.activiti
activiti-diagram-rest
${activiti.version}
org.activiti
activiti-modeler
${activiti.version}
org.activiti
activiti-simple-workflow
${activiti.version}
org.activiti
activiti-spring
${activiti.version}
org.apache.xmlgraphics
batik-codec
${batik.version}
org.apache.xmlgraphics
batik-css
${batik.version}
org.apache.xmlgraphics
batik-svg-dom
${batik.version}
org.apache.xmlgraphics
batik-svggen
${batik.version}
在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
翻车,启动失败!
错误日志
(此处省略)
......
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: 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.(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
此处移除security安全校验方法为修改Application启动类。
@SpringBootApplication(exclude = { org.activiti.spring.boot.SecurityAutoConfiguration.class,
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class })
到此步,Springboot后端的配置成功。下面处理前端页面。
使用压缩工具解压,如图:
在Springboot的项目的resource目录的static文件夹下新建一个activiti-explorer文件夹。(此处根据自己要求是否新建文件夹)
复制完成后如下:
stencilset.json在activiti-webapp-explorer2-5.23.0.war的文件夹下路径:
activiti-webapp-explorer2-5.23.0\WEB-INF\classes
将stencilset.json文件复制到 项目工程的 resource目录下,给前台页面提供报文。
Js的文件路径为:
src\main\resources\static\activiti-explorer\editor-app\app-cfg.js
删除activiti-explorer/service 修改后的值为:
接口文件在activiti-modeler.jar中
org.activiti
activiti-modeler
${activiti.version}
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 })
启动完成后,输入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
https://blog.csdn.net/lgllionky/article/details/78551481
https://blog.csdn.net/jiaoshaoping/article/details/80748065