Spring 与 Spring 数据 Rest 集成:来自 outbound-gateway 的响应为空负载
Spring Integration with Spring Data Rest: empty payload in response from outbound-gateway
我正在使用 Spring 集成 调用 Spring 数据 Rest URL一个 <int-http:outbound-gateway>
.
我的调用是一个简单的 HTTP GET 到已知资源 URL(在我的例子中,"examples")。
这是<int-http:outbound-gateway>
的配置:
<int-http:outbound-gateway id="internalGW" request-channel="dataRestChannel"
encode-uri="true" url-expression="payload"
http-method="GET" extract-request-payload="true"
header-mapper="headerMapper">
</int-http:outbound-gateway>
在日志中我可以看到这条消息:
The 'extractPayload' attribute has no relevance for the current
request since the HTTP Method is 'GET', and no request body will be
sent for that method.
我想这是指 http-method="GET" extract-request-payload="true"
配置,但我不知道这个警告是否与问题相关。
这是使用包含要调用的 REST url 的消息调用出站通道:
public Object invokeUrl(String url){
MessagingChannel messagingChannel = (MessagingChannel)ApplicationContextResolver.getApplicationContext().getBean("requestChannelBean");
MessageChannel dataRestChannel = messagingChannel.getDataRestChannel();
MessagingTemplate messagingTemplate = new MessagingTemplate();
Message<?> requestMessage = MessageBuilder.withPayload(url).build();
Message<?> response = messagingTemplate.sendAndReceive(dataRestChannel, requestMessage);
return response.getPayload();
}
调用正常,我有一个 HTTP 状态代码 200;这是 response.getPayload():
<200 OK,
{
Server=[Apache-Coyote/1.1],
Cache-Control=[no-cache,no-store,max-age=0,must-revalidate],
Pragma=[no-cache],
Expires=[0],
X-XSS-Protection=[1; mode=block],
X-Frame-Options=[DENY,DENY],
X-Content-Type-Options=[nosniff,nosniff],
Transfer-Encoding=[chunked],
Date=[Fri,22 Jul 2016 13:03:22 GMT],
Content-Type=[application/hal+json],
Content-Length=[0]
}>
但是,我不明白为什么 "payload body" 是空的,正如您在 Content-Length header.
中看到的
response GenericMessage<T> (id=219)
headers MessageHeaders (id=221)
payload ResponseEntity<T> (id=222)
body null
headers HttpHeaders (id=224)
statusCode HttpStatus (id=159)
如果我在浏览器上使用 GET 直接转到那个 URL,这是我收到的响应:
{
"_embedded": {
"examples": []
},
"_links": {
"self": {
"href": "http://localhost:8080/restapp/api/examples"
},
"profile": {
"href": "http://localhost:8080/restapp/api/profile/examples"
}
}
}
我希望这是响应负载,而不是空负载。
我收到的ResponseEntity.body好像是空的
有没有什么方法可以通过 outbound-gateway 获得与 HTTP get 相同的 JSON 结果?
提前致谢。
更新
根据加里的建议,我已经监控了流量。
这里有请求的详细信息:
Spring 集成请求:
GET http://localhost:8080/restapp/api/examples HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
浏览器请求:
GET http://localhost:8080/restapp/api/examples HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: JSESSIONID=C966FB7DB6B172D530D7C1F4DC57C6B8
请求似乎是一样的,除了一个header(Cookie JSESSIONID,集成上下文中没有)。
更新 2
也许我找到了响应中空负载的原因。
org.springframework.web.client.RestTemplate
的 "extractData"
方法将 object 实例 this.delegate
设置为 null值.
所以,在 return 中有一个 ResponseEntity
object 而没有 body.
@Override
public ResponseEntity<T> extractData(ClientHttpResponse response) throws IOException {
if (this.delegate != null) { // this.delegate is null
T body = this.delegate.extractData(response);
return new ResponseEntity<T>(body, response.getHeaders(), response.getStatusCode());
}
else {
return new ResponseEntity<T>(response.getHeaders(), response.getStatusCode()); // <- it's executed this one
}
}
发现为什么 this.delegate 设置为 null 会很有趣。
您需要将 expected-response-type="java.lang.String"
添加到网关。
我正在使用 Spring 集成 调用 Spring 数据 Rest URL一个 <int-http:outbound-gateway>
.
我的调用是一个简单的 HTTP GET 到已知资源 URL(在我的例子中,"examples")。
这是<int-http:outbound-gateway>
的配置:
<int-http:outbound-gateway id="internalGW" request-channel="dataRestChannel"
encode-uri="true" url-expression="payload"
http-method="GET" extract-request-payload="true"
header-mapper="headerMapper">
</int-http:outbound-gateway>
在日志中我可以看到这条消息:
The 'extractPayload' attribute has no relevance for the current request since the HTTP Method is 'GET', and no request body will be sent for that method.
我想这是指 http-method="GET" extract-request-payload="true"
配置,但我不知道这个警告是否与问题相关。
这是使用包含要调用的 REST url 的消息调用出站通道:
public Object invokeUrl(String url){
MessagingChannel messagingChannel = (MessagingChannel)ApplicationContextResolver.getApplicationContext().getBean("requestChannelBean");
MessageChannel dataRestChannel = messagingChannel.getDataRestChannel();
MessagingTemplate messagingTemplate = new MessagingTemplate();
Message<?> requestMessage = MessageBuilder.withPayload(url).build();
Message<?> response = messagingTemplate.sendAndReceive(dataRestChannel, requestMessage);
return response.getPayload();
}
调用正常,我有一个 HTTP 状态代码 200;这是 response.getPayload():
<200 OK,
{
Server=[Apache-Coyote/1.1],
Cache-Control=[no-cache,no-store,max-age=0,must-revalidate],
Pragma=[no-cache],
Expires=[0],
X-XSS-Protection=[1; mode=block],
X-Frame-Options=[DENY,DENY],
X-Content-Type-Options=[nosniff,nosniff],
Transfer-Encoding=[chunked],
Date=[Fri,22 Jul 2016 13:03:22 GMT],
Content-Type=[application/hal+json],
Content-Length=[0]
}>
但是,我不明白为什么 "payload body" 是空的,正如您在 Content-Length header.
中看到的response GenericMessage<T> (id=219)
headers MessageHeaders (id=221)
payload ResponseEntity<T> (id=222)
body null
headers HttpHeaders (id=224)
statusCode HttpStatus (id=159)
如果我在浏览器上使用 GET 直接转到那个 URL,这是我收到的响应:
{
"_embedded": {
"examples": []
},
"_links": {
"self": {
"href": "http://localhost:8080/restapp/api/examples"
},
"profile": {
"href": "http://localhost:8080/restapp/api/profile/examples"
}
}
}
我希望这是响应负载,而不是空负载。
我收到的ResponseEntity.body好像是空的
有没有什么方法可以通过 outbound-gateway 获得与 HTTP get 相同的 JSON 结果?
提前致谢。
更新
根据加里的建议,我已经监控了流量。
这里有请求的详细信息:
Spring 集成请求:
GET http://localhost:8080/restapp/api/examples HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
浏览器请求:
GET http://localhost:8080/restapp/api/examples HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: JSESSIONID=C966FB7DB6B172D530D7C1F4DC57C6B8
请求似乎是一样的,除了一个header(Cookie JSESSIONID,集成上下文中没有)。
更新 2
也许我找到了响应中空负载的原因。
org.springframework.web.client.RestTemplate
的 "extractData"
方法将 object 实例 this.delegate
设置为 null值.
所以,在 return 中有一个 ResponseEntity
object 而没有 body.
@Override
public ResponseEntity<T> extractData(ClientHttpResponse response) throws IOException {
if (this.delegate != null) { // this.delegate is null
T body = this.delegate.extractData(response);
return new ResponseEntity<T>(body, response.getHeaders(), response.getStatusCode());
}
else {
return new ResponseEntity<T>(response.getHeaders(), response.getStatusCode()); // <- it's executed this one
}
}
发现为什么 this.delegate 设置为 null 会很有趣。
您需要将 expected-response-type="java.lang.String"
添加到网关。