Activiti7集成SpringBoot2官方实例(三):添加ReST调用列出流程定义

@高效码农  June 25, 2019

我们现在可以使用Activiti7流程引擎运行时库运行应用程序,因此我们可以创建一些标准的Spring MVC rest调用来与流程引擎和可用的流程定义进行交互。

添加一些用户和组并启用Web安全性

为了能够与Process Runtime API进行交互,我们需要使用具有 ROLE_ACTIVITI_USER 角色的用户进行身份验证。如果我们只是直接从Java代码调用Process Runtime API,例如来自带有 main 方法 的类,那么我们可以在进行API调用之前直接设置用户上下文。请看这里 的例子。 注意。这样做只是为了玩API而不是真正的生产实现......

我们将创建自己的小ReST API,因此我们希望使用Basic Auth通过Web浏览器进行身份验证。Activiti使用Spring Security,因此我们可以很容易地做到这一点。

src/main/java/org/activiti/training/activiti7apibasicprocessusertaskservicetaskevents包中创建一个名为Activiti7ApplicationConfiguration 的Spring配置类 :

package org.activiti.training.activiti7apibasicprocessusertaskservicetaskevents;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Set up some users and groups that we can use when interacting with the process engine API.
 * We use the testuser in the process definition so we need to include this user.
 *
 * We also enable Web security so we can build a simple ReST API that uses the Process Engine Java API. We need
 * to be authenticated with a user that has the role ROLE_ACTIVITI_USER to be able to use the API.
 */
@Configuration
@EnableWebSecurity
public class Activiti7ApplicationConfiguration extends WebSecurityConfigurerAdapter {

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

 @Override
 @Autowired
 public void configure(AuthenticationManagerBuilder auth) throws Exception {
 auth.userDetailsService(myUserDetailsService());
 }

 @Bean
 public UserDetailsService myUserDetailsService() {

 InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();

 String[][] usersGroupsAndRoles = {
 {"mbergljung", "1234", "ROLE_ACTIVITI_USER", "GROUP_activitiTraining"},
 {"testuser", "1234", "ROLE_ACTIVITI_USER", "GROUP_activitiTraining"},
 {"system", "1234", "ROLE_ACTIVITI_USER"},
 {"admin", "1234", "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;
 }

 @Override
 protected void configure(HttpSecurity http) throws Exception {
 http
 .csrf().disable()
 .authorizeRequests()
 .anyRequest()
 .authenticated()
 .and()
 .httpBasic();
 }

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

设置我们在与流程引擎API交互时可以使用的一些用户和组。我们 在流程定义中使用testuser (分配给用户任务1),因此我们需要包含此用户。我们还启用了Web安全性,因此我们可以构建一个使用Process Engine Java API的简单ReST API。

添加ReST调用以列出流程定义

首先,让我们添加一个列出已部署流程定义的ReST调用。 在org/activiti/training/activiti7apibasicprocessusertaskservicetaskevents包中创建一个名为rest 的新子包。然后在这个新包中添加一个名为ProcessDefinitionsController 的新Spring MVC控制器,如下所示:

package org.activiti.training.activiti7apibasicprocessusertaskservicetaskevents.rest;

import org.activiti.api.process.model.ProcessDefinition;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * ReST controller to interact with deployed process definitions
 *
 */
@RestController
public class ProcessDefinitionsController {
 private Logger logger = LoggerFactory.getLogger(ProcessDefinitionsController.class);

 @Autowired
 private ProcessRuntime processRuntime;

 @GetMapping("/process-definitions")
 public List<ProcessDefinition> getProcessDefinitions() {
 Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
 logger.info("> Available Process definitions: " + processDefinitionPage.getTotalItems());

 for (ProcessDefinition pd : processDefinitionPage.getContent()) {
 logger.info("\t > Process definition: " + pd);
 }

 return processDefinitionPage.getContent();
 }
}

首先注入 ProcessRuntime Spring bean,以便我们可以使用Process Runtime API,它具有以下方法:

public interface ProcessRuntime {
 ProcessRuntimeConfiguration configuration();
 ProcessDefinition processDefinition(String var1);
 Page<ProcessDefinition> processDefinitions(Pageable var1);
 Page<ProcessDefinition> processDefinitions(Pageable var1, GetProcessDefinitionsPayload var2);
 ProcessInstance start(StartProcessPayload var1);
 Page<ProcessInstance> processInstances(Pageable var1);
 Page<ProcessInstance> processInstances(Pageable var1, GetProcessInstancesPayload var2);
 ProcessInstance processInstance(String var1);
 ProcessInstance suspend(SuspendProcessPayload var1);
 ProcessInstance resume(ResumeProcessPayload var1);
 ProcessInstance delete(DeleteProcessPayload var1);
 void signal(SignalPayload var1);
 ProcessDefinitionMeta processDefinitionMeta(String var1);
 ProcessInstanceMeta processInstanceMeta(String var1);
 List<VariableInstance> variables(GetVariablesPayload var1);
 void removeVariables(RemoveProcessVariablesPayload var1);
 void setVariables(SetProcessVariablesPayload var1);
}

在这种情况下,我们只需要 processDefinitions() 方法。该 /过程定义 URL路径用于该休息GET调用。

现在,按照前面的描述打包并运行应用程序。启动应用程序时,您应该看到指示所有内容都已正确实现的日志:

...

2018-08-28 15:12:49.742  INFO 21982 --- [ost-startStop-1] .a.t.a.Activiti7ApplicationConfiguration : > Registering new user: mbergljung with the following Authorities[[ROLE_ACTIVITI_USER, GROUP_activitiTraining]]

2018-08-28 15:12:49.869  INFO 21982 --- [ost-startStop-1] .a.t.a.Activiti7ApplicationConfiguration : > Registering new user: testuser with the following Authorities[[ROLE_ACTIVITI_USER, GROUP_activitiTraining]]

2018-08-28 15:12:49.994  INFO 21982 --- [ost-startStop-1] .a.t.a.Activiti7ApplicationConfiguration : > Registering new user: system with the following Authorities[[ROLE_ACTIVITI_USER]]

2018-08-28 15:12:50.113  INFO 21982 --- [ost-startStop-1] .a.t.a.Activiti7ApplicationConfiguration : > Registering new user: admin with the following Authorities[[ROLE_ACTIVITI_ADMIN]]

…

org.springframework.security.web.authentication.www.BasicAuthenticationFilter@6fdbe764,

...

2018-08-28 15:12:53.119  INFO 21982 --- [  main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/process-definitions],methods=[GET]}" onto public java.util.List<org.activiti.api.process.model.ProcessDefinition> org.activiti.training.activiti7apibasicprocessusertaskservicetaskevents.rest.ProcessDefinitionsController.getProcessDefinitions()
...

转到浏览器并点击 http://localhost:8080/process-definitions,您将看到一个登录对话框。输入具有 ROLE_ACTIVITI_USER 角色的用户的用户名和密码,例如 testuser/1234。然后你应该得到一个像这样的响应:

[
 {
 id: "c68315b2-fa2a-11e8-9c34-acde48001122",
 name: "Sample Process",
 version: 1,
 key: "sampleproc-e9b76ff9-6f70-42c9-8dee-f6116c533a6d"
 }
]

在控制台日志中,您应该看到以下内容:

2018-08-28 15:13:09.678  INFO 21982 --- [nio-8080-exec-1] o.a.t.a.r.ProcessDefinitionsController   : > Available Process definitions: 1

2018-08-28 15:13:09.678  INFO 21982 --- [nio-8080-exec-1] o.a.t.a.r.ProcessDefinitionsController   : > Process definition: ProcessDefinition{id='c68315b2-fa2a-11e8-9c34-acde48001122', name='Sample Process', key='sampleproc-e9b76ff9-6f70-42c9-8dee-f6116c533a6d', description='null', formKey='null', version=1}


评论已关闭

  1. 老马

    我想问个问题,Activiti7是基于Spring Cloud Gateway的,而Spring Cloud Gateway是基于WebFlux的,你这样使用@EnableWebSecurity来配置Spring Security,将来整个项目完全整合到一起后不会冲突么?(Spring Cloud Gateway与Spring Security整合必须、只能使用@EnableWebFluxSecurity)。

  2. 你这个加了验证 之前的druid 和 swagger 都用不了怎么解决啊

    1. @color

      可以用

  3. hzw

    如何将其封装成restful接口对外提供服务?

    1. @hzw

      看这篇文章:https://www.xugj520.cn/archives/activiti_swagger_druid.html
      系列文章:https://www.xugj520.cn/category/Activiti/