[JAVA] How to apply HandlerInterceptor to http inbound-gateway of Spring Integration

I'm playing with Spring Integration at work right now, and I'm using a Bean-defined Handler (HttpRequestHandlingMessagingGateway) using Http.inboundGateway(Java DSL) or<http-int: inbound-gateway>(XML namespace). I was a little troubled because I couldn't apply Spring MVC'sHandlerInterceptor to), but I found out how to apply it after following the source of ʻIntegrationRequestMappingHandlerMapping`.

In Spring Integration

Bean definition example of Handler using JavaDSL


@Bean
public IntegrationFlow greetingInboundGatewayFlow(MessageChannel httpInboundChannel) {
  return IntegrationFlows.from(Http.inboundGateway("/greeting")
      .requestMapping(mapping -> mapping.methods(HttpMethod.GET))
      .requestChannel(httpInboundChannel)
  ).get();
}

Bean definition example of Handler using XML namespace


<http-int:inbound-gateway
    path="/greeting" supported-methods="GET"
    request-channel="httpRequestChannel"/>

By defining a bean such as

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/greeting")
@RestController
public class GreetingRestController {
  @GetMapping
  public String greeting() {
    // ...
    return responseMessage;
  }
}

You can publish the same endpoint as when you created the Controller.

If it is a normal Spring MVC (Handler based on @ RequestMapping) ...

If it is a style that implements @RequestMapping method in Controller class, you can applyHandlerInterceptor by defining Bean as below.

Bean definition example by JavaConfig


@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MessageLoggingHandlerInterceptor())
                .addPathPatterns("/**") //Applicable path(pattern)To specify
                .excludePathPatterns("/static/**"); //Paths to exclude(pattern)To specify
    }
}

Bean definition example by XML


<mvc:interceptors>
  <mvc:interceptor>
    <mvc:mapping path="/**"/>
    <mvc:exclude-mapping path="/static/**"/>
    <bean class="com.example.MessageLoggingHandlerInterceptor"/>
  </mvc:interceptor>
</mvc:interceptors>

With http inbound-gateway of Spring Integration ...

Handler defined using http inbound-gateway of Spring Integration manages request mapping separately from normal Spring MVC. Specifically, request mapping is managed in a bean created from a class called ʻIntegrationRequestMappingHandlerMapping, and the one managed in the bean of ʻIntegrationRequestMappingHandlerMapping is applied to HandlerInterceptor.

To apply HandlerInterceptor to http inbound-gateway of Spring Integration ...

ʻIntegrationRequestMappingHandlerMapping (to be exact, ʻAbstractHandlerMapping, which is the parent class of ʻIntegrationRequestMappingHandlerMapping), from the DI container, HandlerInterceptor(to be exact,HandlerInterceptor and" Apply path "and" Exclude path "are held in MappedInterceptor. ) Is automatically detected, so all you have to do is define the Bean of HandlerInterceptor`.

Bean definition example by JavaConfig


@Bean
public MappedInterceptor customHandlerInterceptor() {
  return new MappedInterceptor(
      new String[]{"/**"},
      new String[]{"/static/**"},
      new MessageLoggingHandlerInterceptor());
}

Bean definition example by XML


<bean class="org.springframework.web.servlet.handler.MappedInterceptor">
  <constructor-arg name="includePatterns" value="/**"/>
  <constructor-arg name="excludePatterns" value="/static/**"/>
  <constructor-arg name="interceptor">
    <bean class="com.example.MessageLoggingHandlerInterceptor"/>
  </constructor-arg>
</bean>

However ... If you need to define multiple HanderInterceptors and control the application order, there is no guarantee that the bean definition order = application order, so define the Bean of ʻIntegrationRequestMappingHandlerMappingand explicitlyHanderInterceptor You must specify `.

Bean definition by JavaConfig


@Bean
public IntegrationRequestMappingHandlerMapping integrationRequestMappingHandlerMapping() { //Bean name must be integrationRequestMappingHandlerMapping
  IntegrationRequestMappingHandlerMapping mapping = new IntegrationRequestMappingHandlerMapping();
  mapping.setOrder(0); //order must be 0
  mapping.setInterceptors( //Add Mapped Interceptor in the order you want to apply
      new MappedInterceptor(new String[] {"/**"}, new String[] {"/static/**"},
          new CustomHandlerInterceptor()),
      new MappedInterceptor(new String[] {"/**"}, new String[] {"/static/**"},
          new MessageLoggingHandlerInterceptor()));
  return mapping;
}

Bean definition example by XML


<bean id="integrationRequestMappingHandlerMapping"
      class="org.springframework.integration.http.inbound.IntegrationRequestMappingHandlerMapping">
  <property name="order" value="0"/>
  <property name="interceptors">
    <array>
      <bean class="org.springframework.web.servlet.handler.MappedInterceptor">
        <constructor-arg name="includePatterns" value="/**"/>
        <constructor-arg name="excludePatterns" value="/static/**"/>
        <constructor-arg name="interceptor">
          <bean class="com.example.CustomHandlerInterceptor"/>
        </constructor-arg>
      </bean>
      <bean class="org.springframework.web.servlet.handler.MappedInterceptor">
        <constructor-arg name="includePatterns" value="/**"/>
        <constructor-arg name="excludePatterns" value="/static/**"/>
        <constructor-arg name="interceptor">
          <bean class="com.example.MessageLoggingHandlerInterceptor"/>
        </constructor-arg>
      </bean>
    </array>
  </property>
</bean>

Summary

If you want to publish an endpoint for HTTP, you can make a controller normally! !! However, since it is necessary to support protocols other than HTTP in the project I am currently involved in, I am trying to match the architecture of inter-system cooperation using Spring Integration. Basically, I'm thinking of doing common processing in the world of Spring Integration, but some processing (communication log output etc.) seems to need to be done before entering the world of Spring Integration, so HandlerInterceptor It feels like I've tried to use it.

Recommended Posts

How to apply HandlerInterceptor to http inbound-gateway of Spring Integration
How to access Socket directly with the TCP function of Spring Integration
How to use CommandLineRunner in Spring Batch of Spring Boot
How to boot by environment with Spring Boot of Maven
How to use Lombok in Spring
How to use Spring Data JDBC
[How to install Spring Data Jpa]
How to set Spring Boot + PostgreSQL
How to use setDefaultCloseOperation () of JFrame
How to use ModelMapper (Spring boot)
How to realize huge file upload with Rest Template of Spring
How to apply thymeleaf changes to the browser immediately with #Spring Boot + maven
[Spring Boot] I investigated how to implement post-processing of the received request.
How to read Body of Request multiple times with Spring Boot + Spring Security
How to check before sending a message to the server with Spring Integration
How to name variables 7 selections of discomfort
[java] Summary of how to handle char
How to include Spring Tool in Eclipse 4.6.3?
Summary of how to write annotation arguments
Output HTTP header of google-http-client to log
How to determine the number of parallels
Summary of going to JJUG CCC 2019 Spring
[Java] [Maven3] Summary of how to use Maven3
How to sort the List of SelectItem
[Spring MVC] How to pass path variables
How to write Spring AOP pointcut specifier
How to split Spring Boot message file
How to check the latest version of io.spring.platform to describe in pom.xml of Spring (STS)
How to set environment variables in the properties file of Spring boot application
JDBC promises and examples of how to write
How to find the cause of the Ruby error
[java] Summary of how to handle character strings
[Rails] Introduction of pry-rails ~ How to debug binding.pry
Summary of how to create JSF self-made tags
Customize how to divide the contents of Recyclerview
How to use MyBatis2 (iBatis) with Spring Boot 1.4 (Spring 4)
[Bcrypt] how to cancel presence: true of has_secure_password
[Java] Summary of how to abbreviate lambda expressions
Understand how to share Spring DB connection (DB transaction)
How to use built-in h2db with spring boot
How to use "sign_in" in integration test (RSpec)
How to make Spring Boot Docker Image smaller
How to use Spring Boot session attributes (@SessionAttributes)
The story of raising Spring Boot 1.5 series to 2.1 series
How to get today's day of the week
Output of how to use the slice method
How to add a classpath in Spring Boot
How to use enum (introduction of Japanese notation)
[Swift UI] How to disable ScrollsToTop of ScrollView
How to use JQuery in js.erb of Rails6
How to bind to property file in Spring Boot
How to display the result of form input
http: // localhost: How to change the port number
Apply Twitter Bootstrap 4 to Spring Boot 2 using Webjars
How to define multiple orm.xml in Spring4, JPA2.1
[Java] How to get the authority of the folder
How to specify index of JavaScript for statement
[Spring Boot] How to refer to the property file
Spring Boot --How to set session timeout time
How to request by passing an array to the query with HTTP Client of Ruby