ApplicationConfiguration.java
路径:flowable-engine-flowable-6.4.1\modules\flowable-ui-modeler\flowable-ui-modeler-conf\src\main\java\org\flowable\ui\modeler\conf
原因:这个文件是启动中必要的配置文件,需要做修改,详细的可以看下 app 中启动类,文件路径随意
代码如下:
与源码中的区别是注释了一些IDM相关的配置
/* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.flowable.modeler.config.flowable; import org.flowable.ui.common.service.idm.RemoteIdmService; import org.flowable.ui.modeler.properties.FlowableModelerAppProperties; import org.flowable.ui.modeler.servlet.ApiDispatcherServletConfiguration; import org.springframework.boot.autoconfigure.webservices.WebServicesProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; @Configuration @EnableConfigurationProperties(FlowableModelerAppProperties.class) @ComponentScan(basePackages = { // "org.flowable.ui.modeler.conf", "org.flowable.ui.modeler.repository", "org.flowable.ui.modeler.service", // "org.flowable.ui.modeler.security", //授权方面的都不需要 // "org.flowable.ui.common.conf", // flowable 开发环境内置的数据库连接 // "org.flowable.ui.common.filter", // IDM 方面的过滤器 "org.flowable.ui.common.service", "org.flowable.ui.common.repository", // // "org.flowable.ui.common.security",//授权方面的都不需要 "org.flowable.ui.common.tenant" },excludeFilters = { // 移除 RemoteIdmService @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = RemoteIdmService.class), } ) public class ApplicationConfiguration { @Bean public ServletRegistrationBean modelerApiServlet(ApplicationContext applicationContext) { AnnotationConfigWebApplicationContext dispatcherServletConfiguration = new AnnotationConfigWebApplicationContext(); dispatcherServletConfiguration.setParent(applicationContext); dispatcherServletConfiguration.register(ApiDispatcherServletConfiguration.class); DispatcherServlet servlet = new DispatcherServlet(dispatcherServletConfiguration); ServletRegistrationBean registrationBean = new ServletRegistrationBean(servlet, "/api/*"); registrationBean.setName("Flowable Modeler App API Servlet"); registrationBean.setLoadOnStartup(1); registrationBean.setAsyncSupported(true); return registrationBean; } }
AppDispatcherServletConfiguration.java
路径:flowable-engine-flowable-6.4.1\modules\flowable-ui-modeler\flowable-ui-modeler-conf\src\main\java\org\flowable\ui\modeler\servlet
原因:这个文件是启动中必要的配置文件,需要做修改,详细的可以看下 app 中启动类,文件路径随意,这里面有请求处理逻辑,我们需要重新设置一下用户认证(IDM)的部分
代码如下:
/* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.flowable.modeler.config.flowable; import org.flowable.ui.modeler.rest.app.EditorGroupsResource; import org.flowable.ui.modeler.rest.app.EditorUsersResource; import org.flowable.ui.modeler.rest.app.StencilSetResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; import org.springframework.web.servlet.i18n.SessionLocaleResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @Configuration @ComponentScan(value = { "org.flowable.ui.modeler.rest.app", // 不加载 rest,因为 getAccount 接口需要我们自己实现 // "org.flowable.ui.common.rest" },excludeFilters = { // 移除 EditorUsersResource 与 EditorGroupsResource,因为不使用 IDM 部分 @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = EditorUsersResource.class), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = EditorGroupsResource.class), // 配置文件用自己的 @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = StencilSetResource.class), } ) @EnableAsync public class AppDispatcherServletConfiguration implements WebMvcRegistrations { private static final Logger LOGGER = LoggerFactory.getLogger(AppDispatcherServletConfiguration.class); @Bean public SessionLocaleResolver localeResolver() { return new SessionLocaleResolver(); } @Bean public LocaleChangeInterceptor localeChangeInterceptor() { LOGGER.debug("Configuring localeChangeInterceptor"); LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); localeChangeInterceptor.setParamName("language"); return localeChangeInterceptor; } @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { LOGGER.debug("Creating requestMappingHandlerMapping"); RequestMappingHandlerMapping requestMappingHandlerMapping = new RequestMappingHandlerMapping(); requestMappingHandlerMapping.setUseSuffixPatternMatch(false); requestMappingHandlerMapping.setRemoveSemicolonContent(false); Object[] interceptors = { localeChangeInterceptor() }; requestMappingHandlerMapping.setInterceptors(interceptors); return requestMappingHandlerMapping; } }
DatabaseAutoConfiguration.java
Flowable 是基于 liquibase 进行数据库自动管理与追踪的
所以我们还需要加一个 liquibase 的配置类,在config/flowable
中添加一个DatabaseConfiguration
类(可以把org.flowable.ui.modeler.conf.DatabaseConfiguration
下的复制下来改一改)
代码如下:
package com.flowable.modeler.config.flowable; import liquibase.Liquibase; import liquibase.database.Database; import liquibase.database.DatabaseConnection; import liquibase.database.DatabaseFactory; import liquibase.database.jvm.JdbcConnection; import liquibase.exception.DatabaseException; import liquibase.resource.ClassLoaderResourceAccessor; import org.flowable.ui.common.service.exception.InternalServerErrorException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; @Configuration public class DatabaseAutoConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseAutoConfiguration.class); protected static final String LIQUIBASE_CHANGELOG_PREFIX = "ACT_DE_"; @Bean public Liquibase liquibase(DataSource dataSource) { LOGGER.info("Configuring Liquibase"); Liquibase liquibase = null; try { DatabaseConnection connection = new JdbcConnection(dataSource.getConnection()); Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection); database.setDatabaseChangeLogTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogTableName()); database.setDatabaseChangeLogLockTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogLockTableName()); liquibase = new Liquibase("META-INF/liquibase/flowable-modeler-app-db-changelog.xml", new ClassLoaderResourceAccessor(), database); liquibase.update("flowable"); return liquibase; } catch (Exception e) { throw new InternalServerErrorException("Error creating liquibase database", e); } finally { closeDatabase(liquibase); } } private void closeDatabase(Liquibase liquibase) { if (liquibase != null) { Database database = liquibase.getDatabase(); if (database != null) { try { database.close(); } catch (DatabaseException e) { LOGGER.warn("Error closing database", e); } } } } }
之后还需要添加mybatis扫描XML的配置
classpath:/META-INF/modeler-mybatis-mappings/*.xml
如下面mybatis的全部配置,添加到mapper-locations
后即可
mybatis: # 新增 modeler-mybatis-mappings xml 扫描 mapper-locations: mapper/*/*.xml, classpath*:mapper/*.xml, classpath:/META-INF/modeler-mybatis-mappings/*.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 参数配置 configuration-properties: # 配置流程引擎参数,详情可见 DatabaseConfiguration blobType: BLOB boolValue: TRUE # 不要设置库名,否则会出现双库名 bug prefix: ''
汉化操作配置
StencilSetResource.java
路径:flowable-engine-flowable-6.4.1\modules\flowable-ui-modeler\flowable-ui-modeler-rest\src\main\java\org\flowable\ui\modeler\rest\app
同时在 resource 下新建一个 stencilset 文件夹用来放汉化文件
原因:国际化配置加载,为了使用我们自己的汉化文件因此把文件拿出来并修改,文件路径随意
PS:复制出来后要对这个文件进行重命名,否则会与 Jar 包里的文件产生 Bean 存在的冲突
代码如下(重命名后叫 FlowableStencilSetResource.java):
/* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.flowable.modeler.config.flowable; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.flowable.ui.common.service.exception.InternalServerErrorException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/app") public class FlowableStencilSetResource { private static final Logger LOGGER = LoggerFactory.getLogger(FlowableStencilSetResource.class); @Autowired protected ObjectMapper objectMapper; @RequestMapping(value = "/rest/stencil-sets/editor", method = RequestMethod.GET, produces = "application/json") public JsonNode getStencilSetForEditor() { try { JsonNode stencilNode = objectMapper.readTree(this.getClass().getClassLoader().getResourceAsStream("stencilset/stencilset_bpmn.json")); return stencilNode; } catch (Exception e) { LOGGER.error("Error reading bpmn stencil set json", e); throw new InternalServerErrorException("Error reading bpmn stencil set json"); } } @RequestMapping(value = "/rest/stencil-sets/cmmneditor", method = RequestMethod.GET, produces = "application/json") public JsonNode getCmmnStencilSetForEditor() { try { JsonNode stencilNode = objectMapper.readTree(this.getClass().getClassLoader().getResourceAsStream("stencilset/stencilset_cmmn.json")); return stencilNode; } catch (Exception e) { LOGGER.error("Error reading bpmn stencil set json", e); throw new InternalServerErrorException("Error reading bpmn stencil set json"); } } }