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.
@ 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>
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.
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>
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