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's
HandlerInterceptor 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 HanderInterceptor
s and control the application order, there is no guarantee that the bean definition order = application order, so define the Bean of ʻIntegrationRequestMappingHandlerMappingand explicitly
HanderInterceptor 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