springboot集成flowable modeler 6.5.0整合实现在线编辑免登录

本文档详细记录了如何将Flowable工作流引擎集成到Spring Boot应用程序中,包括从官方源码中复制静态资源,配置POM依赖,创建配置类以集成Flowable REST API,解决ACT_DE包生成问题以及实现免登录。此外,还介绍了配置文件设置和最终效果展示。
摘要由CSDN通过智能技术生成

这里写自定义目录标题


因公司需求需要用到工作流,选型flowable,本篇博客记录下整合

 

把官方flowable-ui-modeler-app\src\main\resources\static下面的代码拷贝至我们自己的工程

在这里插入图片描述

Pom引入

<?xml version="1.0" encoding="UTF-8"?>


4.0.0

<groupId>com.promote</groupId>
<artifactId>flowable</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
</parent>

<properties>
    <flowable.version>6.4.2</flowable.version>
</properties>

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!--<dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-spring-boot-starter</artifactId>
        <version>6.4.2</version>
    </dependency>-->
    <!--flowable支持  包含flowable-spring-boot-starter-->
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-spring-boot-starter-process</artifactId>
        <version>6.4.2</version>
    </dependency>

    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-rest</artifactId>
        <version>6.4.2</version>
    </dependency>

    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-ui-modeler-rest</artifactId>
        <version>${flowable.version}</version>
    </dependency>
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-ui-modeler-conf</artifactId>
        <version>${flowable.version}</version>
    </dependency>
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-ui-modeler-logic</artifactId>
        <version>${flowable.version}</version>
    </dependency>


    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-ui-common</artifactId>
        <version>${flowable.version}</version>
    </dependency>
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-ui-modeler-rest</artifactId>
        <version>${flowable.version}</version>
    </dependency>
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-idm-spring-configurator</artifactId>
        <version>${flowable.version}</version>
    </dependency>
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-ui-idm-rest</artifactId>
        <version>${flowable.version}</version>
    </dependency>
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-ui-idm-conf</artifactId>
        <version>${flowable.version}</version>
    </dependency>

    <dependency>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-core</artifactId>
        <version>3.6.2</version>
    </dependency>

    <!--<dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-ui-modeler-logic</artifactId>
        <version>6.4.2</version>
    </dependency>-->

    <dependency>
        <groupId>org.mariadb.jdbc</groupId>
        <artifactId>mariadb-java-client</artifactId>
        <version>2.5.2</version>
    </dependency>

    <!--阿里druid支持-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.21</version>
    </dependency>

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.1</version>
    </dependency>

    <!--Mybatis-plus支持-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.1.10</version>
    </dependency>
    <dependency>
        <groupId>com.github.jsqlparser</groupId>
        <artifactId>jsqlparser</artifactId>
        <version>2.1</version>
    </dependency>

    <!--lombok支持-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
        <scope>provided</scope>
    </dependency>

    <!--swagger-ui-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>4.6.8</version>
    </dependency>

</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169

新增2个配置类 集成flowable rest api

@Configuration
@ComponentScan(value = {“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),
})
@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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

}

@Configuration
@EnableConfigurationProperties(FlowableModelerAppProperties.class)
@ComponentScan(basePackages = {
“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”},
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = RemoteIdmService.class)
})
public class ApplicationConfiguration {

@Bean
public ServletRegistrationBean apiServlet(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 IDM App API Servlet");
    registrationBean.setLoadOnStartup(1);
    registrationBean.setAsyncSupported(true);
    return registrationBean;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

}

启动类中:
@Import({
ApplicationConfiguration.class,
AppDispatcherServletConfiguration.class
})
@EnableSwagger2
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class FlowableApplication {

public static void main(String[] args) {
    SpringApplication.run(FlowableApplication.class, args);
}
  • 1
  • 2
  • 3

}

ACT_DE的包无法生成,使用如下的配置类

@Configuration
public class DatabaseConfiguration {

private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseConfiguration.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);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

}

破解登录

自定义查询账号信息
@RestController
@RequestMapping("/custome")
public class CustomeAccountResource {

/**
 * GET /rest/account -> get the current user.
 */
@RequestMapping(value = "/rest/account", method = RequestMethod.GET, produces = "application/json")
public UserRepresentation getAccount() {
    UserRepresentation userRepresentation = new UserRepresentation();
    userRepresentation.setFirstName("admin");
    userRepresentation.setLastName("admin");
    userRepresentation.setFullName("admin");
    userRepresentation.setId("admin");
    List<String> pris = new ArrayList<>();
    pris.add(DefaultPrivileges.ACCESS_MODELER);
    pris.add(DefaultPrivileges.ACCESS_IDM);
    pris.add(DefaultPrivileges.ACCESS_ADMIN);
    pris.add(DefaultPrivileges.ACCESS_TASK);
    pris.add(DefaultPrivileges.ACCESS_REST_API);
    userRepresentation.setPrivileges(pris);

    if (userRepresentation != null) {
        return userRepresentation;
    } else {
        throw new NotFoundException();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

}

在这里插入图片描述
自定义安全工具类SecurityUtils 包名和官方包保持一致
package org.flowable.ui.common.security;

import org.flowable.idm.api.User;
import org.flowable.ui.common.model.RemoteUser;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.ArrayList;
import java.util.List;

/**

  • 自定义安全工具类
  • @author xue.hairui
  •  

*/
public class SecurityUtils {

private static User assumeUser;

private SecurityUtils() {
}

/**
 * Get the login of the current user.
 */
public static String getCurrentUserId() {
    User user = getCurrentUserObject();
    if (user != null) {
        return user.getId();
    }
    return null;
}

/**
 * @return the {@link User} object associated with the current logged in user.
 */
public static User getCurrentUserObject() {
    if (assumeUser != null) {
        return assumeUser;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

// User user = null;
// FlowableAppUser appUser = getCurrentFlowableAppUser();
// if (appUser != null) {
// user = appUser.getUserObject();
// }

    RemoteUser user = new RemoteUser();
  • 1

// FlowableAppUser appUser = getCurrentFlowableAppUser();
// if (appUser != null) {
// user = appUser.getUserObject();
// }
user.setId(“admin”);
user.setDisplayName(“admin”);
user.setFirstName(“admin”);
user.setLastName(“admin”);
user.setEmail(“admin@admin.com”);
user.setPassword(“test”);
List pris = new ArrayList<>();
pris.add(DefaultPrivileges.ACCESS_MODELER);
pris.add(DefaultPrivileges.ACCESS_IDM);
pris.add(DefaultPrivileges.ACCESS_ADMIN);
pris.add(DefaultPrivileges.ACCESS_TASK);
pris.add(DefaultPrivileges.ACCESS_REST_API);
user.setPrivileges(pris);
return user;
}

public static FlowableAppUser getCurrentFlowableAppUser() {
    FlowableAppUser user = null;
    SecurityContext securityContext = SecurityContextHolder.getContext();
    if (securityContext != null && securityContext.getAuthentication() != null) {
        Object principal = securityContext.getAuthentication().getPrincipal();
        if (principal instanceof FlowableAppUser) {
            user = (FlowableAppUser) principal;
        }
    }
    return user;
}

public static boolean currentUserHasCapability(String capability) {
    FlowableAppUser user = getCurrentFlowableAppUser();
    for (GrantedAuthority grantedAuthority : user.getAuthorities()) {
        if (capability.equals(grantedAuthority.getAuthority())) {
            return true;
        }
    }
    return false;
}

public static void assumeUser(User user) {
    assumeUser = user;
}

public static void clearAssumeUser() {
    assumeUser = null;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

}

配置文件如下:

在这里插入图片描述

大功告成,效果图如下

访问:http://localhost:9016/
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值