SpringBoot integrates Activiti7 implementation code

SpringBoot integrates Activiti7 implementation code

After the official release of Activiti7, it has fully supported integrated development with SpringBoot2.x. We can introduce the coordinates of the integrated development of Activiti7 and SpringBoot into the project, so that SpringBoot can support Activti7 integration.

1. Create a SpringBoot project using IDEA

Introduce relevant dependencies in the project's pom.xml file. The specific dependencies are as follows

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <groupId>com.example</groupId>
  <artifactId>activiti</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>activiti</name>
  <description>Demo project for Spring Boot</description>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
  </properties>

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

    <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.activiti</groupId>
      <artifactId>activiti-spring-boot-starter</artifactId>
      <version>7.0.0.Beta2</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.5</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.27</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>

2.application.yml file configuration

In order to put the tables generated by Activiti7 into the MySQL database, you need to add relevant configurations in the configuration file application.yml

server:
 port: 8085
spring:
 application:
  name: spring-activiti
 datasource:
  url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&nullCatalogMeansCurrent=true
  Username: root
  password: 123456
  driver-class-name: com.mysql.jdbc.Driver
 activiti:
  #1.flase: default value. When activiti starts, it will compare the versions saved in the database table. If there is no table or the versions do not match, an exception #2 will be thrown. true: activiti will update all tables in the database. If the table does not exist, it is automatically created #3.create_drop: Create the table when activiti starts and delete the table when it is shut down (the engine must be shut down manually to delete the table)
  #4.drop-create: Delete the original old table when activiti starts, and then create a new table (no need to shut down the engine manually)
  database-schema-update: true
  #Check whether the history table exists db-history-used: true
  #Record history level The configurable history levels are none, activity, audit, full
  history-level: full
  #Check process files. By default, check the process files in the processes folder under resources. check-process-definitions: false

3. Add SpringSecurity security framework integration configuration

After Activiti7 is integrated with SpringBoot, the SpringSecurity security framework is integrated by default, so we need to prepare the relevant user permission configuration information integrated by SpringSecurity

1) Add SecurityUtil class

A component added to quickly configure the SpringSecurity security framework.

@Component
public class SecurityUtil {

  private Logger logger = LoggerFactory.getLogger(SecurityUtil.class);

  @Autowired
  @Qualifier("myUserDetailsService")
  private UserDetailsService userDetailsService;

  public void logInAs(String username) {

    UserDetails user = userDetailsService.loadUserByUsername(username);
    if (user == null) {
      throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user");
    }
    logger.info("> Logged in as: " + username);
    SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {
      @Override
      public Collection<? extends GrantedAuthority> getAuthorities() {
        return user.getAuthorities();
      }

      @Override
      public Object getCredentials() {
        return user.getPassword();
      }

      @Override
      public Object getDetails() {
        return user;
      }

      @Override
      public Object getPrincipal() {
        return user;
      }

      @Override
      public boolean isAuthenticated() {
        return true;
      }

      @Override
      public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

      }

      @Override
      public String getName() {
        return user.getUsername();
      }
    }));
    org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
  }
}

This class can be found in the Example officially provided by Activiti7.

2) Add the DemoApplicationConfig class

Its role is to implement the configuration of user permissions of the SpringSecurity framework so that we can use user permission information in the system

@Configuration
public class DemoApplicationConfiguration {

  private Logger logger = LoggerFactory.getLogger(DemoApplicationConfiguration.class);

  @Bean
  public UserDetailsService myUserDetailsService() {

    InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();

    String[][] usersGroupsAndRoles = {
        {"salaboy", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
        {"ryandawsonuk", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
        {"erdemedeiros", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
        {"other", "password", "ROLE_ACTIVITI_USER", "GROUP_otherTeam"},
        {"system", "password", "ROLE_ACTIVITI_USER"},
        {"admin", "password", "ROLE_ACTIVITI_ADMIN"},
    };

    for (String[] user : usersGroupsAndRoles) {
      List<String> authoritiesStrings = Arrays.asList(Arrays.copyOfRange(user, 2, user.length));
      logger.info("> Registering new user: " + user[0] + " with the following Authorities[" + authoritiesStrings + "]");
      inMemoryUserDetailsManager.createUser(new User(user[0], passwordEncoder().encode(user[1]),
          authoritiesStrings.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList())));
    }


    return inMemoryUserDetailsManager;
  }


  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }

}

4) Create a test class

@SpringBootTest
@Slf4j
class ActivitiApplicationTests {

  @Autowired
  private ProcessEngine processEngine;

  /**
   * Deployment of process definition */
  @Test
  public void createDeploy() { 
    RepositoryService repositoryService = processEngine.getRepositoryService();

    Deployment deployment = repositoryService.createDeployment()
        .addClasspathResource("diagram/holiday.bpmn")//Add bpmn resources.addClasspathResource("diagram/holiday.png")
        .name("Leave Application Form Process")
        .deploy(); 
        
    log.info("Process deployment id:" + deployment.getName());
    log.info("Process deployment name:" + deployment.getId());
  }
}

Running results:

Problems encountered:

1) The history table is not generated by default and needs to be configured in application.yml

spring:
 activiti:
  #Check whether the history table exists db-history-used: true
  #Record history level The configurable history levels are none, activity, audit, full
  history-level: full

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Use springboot activiti to close the verification automatic deployment mode
  • Springboot integrated activity process diagram
  • SpringBoot integrated activiti sample code
  • Analysis of the integration process of Spring and activiti
  • Springboot integrates activity automatic deployment and deployment file naming process

<<:  jQuery achieves large-screen scrolling playback effect

>>:  Detailed explanation of referential integrity in SQL (one-to-one, one-to-many, many-to-many)

Recommend

Mysql 5.7.19 free installation version encountered pitfalls (collection)

1. Download the 64-bit zip file from the official...

Introduction to the use of html base tag target=_parent

The <base> tag specifies the default address...

Detailed explanation of MySQL slow log query

Slow log query function The main function of slow...

Sample code for implementing honeycomb/hexagonal atlas with CSS

I don’t know why, but UI likes to design honeycom...

Select web page drop-down list and div layer covering problem

Questions about select elements in HTML have been...

A simple example of using Vue3 routing VueRouter4

routing vue-router4 keeps most of the API unchang...

A question about border-radius value setting

Problem Record Today I was going to complete a sm...

Native JS to implement real-time clock

Share a real-time clock effect implemented with n...

Conflict resolution when marquee and flash coexist in a page

The main symptom of the conflict is that the FLASH...

Do you know the weird things in Javascript?

Our veteran predecessors have written countless c...

Specific use of ES6 array copy and fill methods copyWithin() and fill()

Table of contents Batch copy copyWithin() Fill ar...

MySQL performance optimization tips

MySQL Performance Optimization MySQL is widely us...

Analyze the method of prometheus+grafana monitoring nginx

Table of contents 1. Download 2. Install nginx an...

Summary of practical experience of HTML knowledge points

1. The table tag is table, tr is row, td is cell, ...