springboot1.5集成flowable6.5.0和对应的modelerUI

1.jar包依赖必须的;



   org.flowable
   flowable-spring-boot-starter
   6.5.0


   org.flowable
   flowable-ui-modeler-rest
   6.5.0


   org.flowable
   flowable-ui-modeler-conf
   6.5.0


   org.flowable
   flowable-ui-modeler-logic
   6.5.0

 

2.配置可视化页面需要的接口;


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.apache.tomcat.jdbc.pool.DataSource;
import org.flowable.ui.common.service.exception.InternalServerErrorException;
import org.flowable.ui.common.service.idm.RemoteIdmService;
import org.flowable.ui.modeler.properties.FlowableModelerAppProperties;
import org.flowable.ui.modeler.rest.app.EditorGroupsResource;
import org.flowable.ui.modeler.rest.app.EditorUsersResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.web.WebMvcRegistrations;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**
 * flowable 配置类
 * sy
 */
@Configuration
@EnableConfigurationProperties({FlowableModelerAppProperties.class})
@ComponentScan(basePackages = {
//        "org.flowable.ui.modeler.conf", // conf
//        "org.flowable.ui.modeler.security", // 授权
//        "org.flowable.ui.common.security",// 授权
//        "org.flowable.ui.common.conf", // flowable 开发环境内置的数据库连接
//        "org.flowable.ui.common.filter", // IDM 方面的过滤器
        "org.flowable.ui.modeler.repository",
        "org.flowable.ui.modeler.service",
        "org.flowable.ui.common.service",
        "org.flowable.ui.common.repository",
        "org.flowable.ui.common.tenant",
        "org.flowable.ui.modeler.rest.app"
          },
        excludeFilters = {
                @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 = RemoteIdmService.class)
        })
@EnableAsync
public class AppDispatcherServletConfiguration implements WebMvcRegistrations {
    private static final Logger LOGGER = LoggerFactory.getLogger(AppDispatcherServletConfiguration.class);


    @Override
    public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
        LOGGER.debug("初始化flowable...");
        RequestMappingHandlerMapping requestMappingHandlerMapping = new RequestMappingHandlerMapping();
        requestMappingHandlerMapping.setUseSuffixPatternMatch(false);
        requestMappingHandlerMapping.setRemoveSemicolonContent(false);
        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
        localeChangeInterceptor.setParamName("language");
        Object[] interceptors = { localeChangeInterceptor };
        requestMappingHandlerMapping.setInterceptors(interceptors);
        return requestMappingHandlerMapping;
    }

    /**
     * 重写Liquibase生成表方法,解决找不到ACT_DE_MODE报错
     * @param dataSource
     * @return
     */
    @Bean
    public Liquibase liquibase(DataSource dataSource) {
        LOGGER.info("Liquibase 开始生成模板信息表");
        Liquibase liquibase = null;
        try {
            DatabaseConnection connection = new JdbcConnection(dataSource.getConnection());
            Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);
            database.setDatabaseChangeLogTableName("ACT_DE_" + database.getDatabaseChangeLogTableName());
            database.setDatabaseChangeLogLockTableName("ACT_DE_" + database.getDatabaseChangeLogLockTableName());

            liquibase = new Liquibase("META-INF/liquibase/flowable-modeler-app-db-changelog.xml", new ClassLoaderResourceAccessor(), database);
            liquibase.update("sy");
            return liquibase;

        } catch (Exception e) {
            throw new InternalServerErrorException("生成模板表失败:", e);
        } finally {
            if (liquibase != null) {
                Database database = liquibase.getDatabase();
                if (database != null) {
                    try {
                        database.close();
                    } catch (DatabaseException e) {
                        LOGGER.warn("关闭Liquibase生成模板表失败:", e);
                    }
                }
            }
        }
    }

    @Override
    public RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() {
        return  new RequestMappingHandlerAdapter();
    }

    @Override
    public ExceptionHandlerExceptionResolver getExceptionHandlerExceptionResolver() {
        return new ExceptionHandlerExceptionResolver();
    }


}

 

3.伪造登陆信息(如果有集成权限框架可根据需要修改);


import com.google.common.cache.LoadingCache;
import org.flowable.idm.api.User;
import org.flowable.ui.common.filter.FlowableCookieFilterCallback;
import org.flowable.ui.common.model.RemoteToken;
import org.flowable.ui.common.model.RemoteUser;
import org.flowable.ui.common.security.FlowableAppUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.RememberMeAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
* FlowableFilter
* sy
*/
@Component
@WebFilter(urlPatterns = {"/app/**", "/api/**"})
public class FlowableFilter extends OncePerRequestFilter {
    private Logger LOGGER = LoggerFactory.getLogger(FlowableFilter.class);


    protected FlowableCookieFilterCallback filterCallback;


    protected LoadingCache tokenCache;


    /**
     * 为flowable伪造用户信息
     * @param request
     * @param response
     * @param filterChain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

            RemoteToken token1 = new RemoteToken(); // 伪造token
            token1.setId("KarkD0DrvtStMirNnlHOpw");
            token1.setValue("kyBmsS7Nl+ScexbUbQk7GQ==");
            token1.setId("123788798");
            token1.setValue("567678");
            token1.setUserId("admin");
            RemoteToken token = token1;//getValidToken(request); // 正常应该从系统中获取
            if (token != null) {
                try {
                    User user = new RemoteUser(); // 伪造用户信息
                    user.setId("admin");
                    user.setFirstName("admin");
                    user.setLastName("admin");
                    user.setEmail("[email protected]");
                    List list = new ArrayList<>(); // 设置菜单权限(重要)
                    list.add(new SimpleGrantedAuthority("access-idm"));
                    list.add(new SimpleGrantedAuthority("access-rest-api"));
                    list.add(new SimpleGrantedAuthority("access-task"));
                    list.add(new SimpleGrantedAuthority("access-modeler"));
                    list.add(new SimpleGrantedAuthority("access-admin"));
                    FlowableAppUser appUser1= new FlowableAppUser(user,"admin",list);


                    FlowableAppUser appUser = appUser1;//userCache.get(token.getUserId());
                    // 设置用户信息
                    SecurityContextHolder.getContext().setAuthentication(new RememberMeAuthenticationToken(token.getId(),appUser, appUser.getAuthorities()));
                } catch (Exception e) {
                    LOGGER.trace("token 获取失败:", e);
                }
                if (filterCallback != null) {
                    filterCallback.onValidTokenFound(request, response, token);
                }
            } else {
                return;
            }

        try {
            filterChain.doFilter(request, response);
        } finally {
            if (filterCallback != null) {
                filterCallback.onFilterCleanup(request, response);
            }
        }
    }

}

 

4.伪造获取用户信息接口/app/rest/account(有集成权限的可根据需要重写);

import org.flowable.ui.common.model.RemoteUser;
import org.flowable.ui.common.model.UserRepresentation;
import org.flowable.ui.common.security.FlowableAppUser;
import org.flowable.ui.common.security.SecurityUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;


/**
* flowable 认证接口
* sy
*/
@RestController
public class DemoController {


    /**
     * 获取当前登陆用户信息
     * @return
     */
    @RequestMapping(value = "/app/rest/account", method = RequestMethod.GET, produces = "application/json")
    public UserRepresentation getAccount() {
        FlowableAppUser appUser = SecurityUtils.getCurrentFlowableAppUser();
        UserRepresentation userRepresentation = new UserRepresentation(appUser.getUserObject());
        if (appUser.getUserObject() instanceof RemoteUser) {
            RemoteUser temp = (RemoteUser) appUser.getUserObject();
            userRepresentation.setPrivileges(temp.getPrivileges());
        }
        return userRepresentation;
    }


}

 

5.主入口文件排除登陆认证(可根据需要不设置)

//排除springsecurity认证
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})

 

6.把flowable-6.5.0解压之后flowable-6.5.0\wars目录下解压flowable-modeler.war;

7.把flowable-modeler.war\WEB-INF\classes\static目录下的所有东西复制到项目的resources/static下的自定义目录下(这里以flowable-modeler为例)

springboot1.5集成flowable6.5.0和对应的modelerUI_第1张图片

8.配置文件;

#工作流配置
# 关闭异步,不关闭历史数据的插入就是异步的,会在同一个事物里面,无法回滚
# 开发可开启会提高些效率,上线需要关闭,开启后不会自动生成数据库表
flowable.async-executor-activate=false
#启用 flowable 端点
management.endpoint.flowable.enabled=false
# 是否需要自动部署流程定义。
flowable.check-process-definitions=false
# 需要添加至引擎的自定义Mybatis映射的FQN
#flowable.custom-mybatis-mappers=classpath:mappers/*.xml
# 设置页面字体
flowable.labelFontName=宋体
flowable.activityFontName=宋体
flowable.annotationFontName=宋体
# 禁用Liquibase
liquibase.enabled=false
# Liquibase自定义配置文件地址resources
#liquibase.change-log=classpath:/db/changelog/db.changelog-master.xml

# mybatis Flowable需要配置xml映射和configuration-properties三个属性
mybatis.mapper-locations=原来的配置,classpath:/META-INF/modeler-mybatis-mappings/*.xml
mybatis.configuration-properties.prefix=
mybatis.configuration-properties.blobType=BLOB
mybatis.configuration-properties.boolValue=TRUE

 

9.第一次启动会初始化数据库;

10.通过http://localhost:端口号/flowable-modeler/index.html访问即可;

 

遇到的问题:
1.org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): xxxx.xxx.xxx.xx;

找不到某个方法,解决方式在步骤2中

你可能感兴趣的:(flowable,工作流,spring,boot)