Spring Integration和Spring MVC:@Controller vs inbound-gateway with service-activator

时间:2016-07-28 14:30:40

标签: spring spring-mvc spring-integration

我想找到使用 Spring Integration HTTP Spring MVC 来管理入站请求的最佳方法。

我的<int-http:inbound-gateway>配置如下:

<!-- CHANNEL -->
<int:channel id="requestChannel">
    <int:dispatcher task-executor="executor"/>
</int:channel>
<int:channel id="outputChannel" />

<!-- INBOUND GATEWAY -->
<int-http:inbound-gateway id="gateway" request-channel="requestChannel"
              path="/service/**" 
              supported-methods="POST"
              reply-channel="outputChannel"
              header-mapper="headerMapper">
</int-http:inbound-gateway>

<!-- SERVICE ACTIVATOR -->
<int:service-activator id="channelServiceActivator"
    ref="channelService"
    input-channel="requestChannel"
    output-channel="outputChannel"
    method="manage"/>

<bean id="channelService"
    class="test.spring.data.rest.xml.channel.ChannelService"/>

通过此集成,在路径URI /service/**上进行的每个HTTP调用都在manage()类的ChannelService方法中处理。 / p>

这是ChannelService类:

public class ChannelService {

    public void manage(Message<?> message){

        // how to get the HttpServletRequest request here ???
    }

}

它的工作原理:正确执行“manage()”方法,并且消息包含正确的有效负载。 但是有一个问题:我没有对ServiceChannel 中输入中收到的HttpServletRequest的任何引用。

如果我使用@Controller的Spring MVC,我可以使用相对@RequestMapping处理每个请求。 如果我想读取请求中包含的有效负载,我必须从HttpServletRequest的inputStream中读取它。在任何地方,我都没有机会在频道中传递消息:

@Controller
@RequestMapping(value="/service")
public class ServiceController {

    @RequestMapping(value="/**")
    public handle(HttpServletRequest request) throws Exception{

        // how to get the Message<?> message passed on the channel here ???

    }

}

如果我同时使用@Controllerinbound-gateway), @Controller映射会胜过入站网关:没有机会如果存在,则处理带有inbound-gateway的servlet路径URI 一个映射相同路径URI的@Controller

所以,我想了解是否有某种方法可以在@Controller中使用Message<?> message,或者在ServiceActivator中使用HttpServletRequest,或者以其他方式来管理这种情况。

提前致谢。

1 个答案:

答案 0 :(得分:3)

您可以通过HttpServletRequesthttp://docs.spring.io/spring-integration/reference/html/http.html#_uri_template_variables_and_expressions)访问MessageHeaders

HttpRequestHandlingEndpointSupport的逻辑如下:

evaluationContext.setVariable("requestAttributes", RequestContextHolder.currentRequestAttributes());

MultiValueMap<String, String> requestParams = this.convertParameterMap(servletRequest.getParameterMap());
evaluationContext.setVariable("requestParams", requestParams);

evaluationContext.setVariable("requestHeaders", new ServletServerHttpRequest(servletRequest).getHeaders());

因此,您可以使用以下子元素配置<int-http:inbound-gateway>

<int-http:header name="requestAttributes" expression="#requestAttributes"/>
<int-http:header name="requestParams" expression="#requestParams"/>
<int-http:header name="requestHeaders" expression="#requestHeaders"/>
<int-http:header name="matrixVariables" expression="#matrixVariables"/>
<int-http:header name="cookies" expression="#cookies"/>

requestAttributesRequestAttributes的实现。标准的是ServletRequestAttributes,您可以在其中找到getRequest()方法。是的,也可以在表达式中使用它:

<int-http:header name="request" expression="#requestAttributes.request"/>

另一方面,您始终可以在自己的代码中使用RequestContextHolder.currentRequestAttributes(),因为它与ThreadLocal绑定。

Spring MVC对Spring Integration一无所知,因此没有任何Message处理。

无论如何你也可以这样走。为此,您应该引入@MessagingGateway并从@Controller

委派逻辑