访问inbound-gateway中的路径以设置标头

时间:2014-08-06 15:08:51

标签: spring-integration spring-ws

我有几个http网关处理不同的URL路径,最终使用公共路由器通道将tehm路由到服务激活器。在发送到路由器之前,我需要从http请求中提取版本和服务名称。版本很简单,我有一个相应的HTTP标头。但是,必须从URL路径中提取服务名称。

一些例子:

/json/ContactService/query = "ContactService"
/json/ContactService/associations/query ="ContactService"
/json/ContactService/1234 = "ContactService"

我有一个相当强力的方法来确定URL路径中的服务:

String service = null;

URL url = new URL(requestUrl);
String path = url.getPath();

String[] parts = path.split("/");

// iterate over the parts of the url and find the service part
for(String s : parts) {
    if(s.indexOf("Service") > -1) {
        service = s;
    }       
}

但是我不喜欢这种方法,就好像服务名称一样,我需要更新代码。另外,它没有考虑URL的斜线和其他细微差别。理想情况下,我想在网关中使用SPeL设置标头,因为每个网关处理不同的路径,我可以使用路径段相应地设置服务名称。

示例(使用SPeL的伪代码):

<int-http:inbound-gateway 
        path="/*Service/query, /*Service/count" request-channel="JSONRequestChannel" reply-channel="JSONResponseChannel"
        supported-methods="POST" reply-timeout="5000" request-payload-type="java.lang.String"
        error-channel="CommonErrorChannel" mapped-request-headers="version, HTTP_REQUEST_HEADERS">
        <int-http:header name="service" expression="path.parts[path.parts.length-2]" />
</int-http:inbound-gateway>


<int-http:inbound-gateway 
        path="/*Service/association/query" request-channel="JSONRequestChannel" reply-channel="JSONResponseChannel"
        supported-methods="POST" reply-timeout="5000" request-payload-type="java.lang.String"
        error-channel="CommonErrorChannel" mapped-request-headers="version, HTTP_REQUEST_HEADERS">
        <int-http:header name="service" expression="path.parts[path.parts.length-3]" />
</int-http:inbound-gateway>

我遇到的一个问题是NPE试图在SPeL中使用http_requestUrl标头;当我尝试在int-header中使用它时似乎没有设置。

1 个答案:

答案 0 :(得分:0)

这是鸡和蛋的问题 - 当创建这些标题时,该消息尚不存在,因此您无法在这些表达式中使用headers['foo']。实际上,这些头文件(URL等)是在创建消息之前添加的最后一件事;这些表达式没有#this个对象,只有variables listed here#pathVariables等)。

为了使它在这里可用,我们必须将它作为变量添加到评估上下文(类似#uri)。但这需要改变框架。

我认为此时您唯一的选择是在网关和路由器之间添加<header-enricher/>(因为http_requestUrl将可用)。

编辑:

或者,您可以直接访问HttpServletRequest,使用此...

<int-http:header name="foo" 
expression="T(org.springframework.web.context.request.RequestContextHolder)
.requestAttributes.request.requestURI"/>

(为了便于阅读,添加了换行符)