【问题标题】:Spring Integration with Spring Data Rest: empty payload in response from outbound-gatewaySpring 与 Spring Data Rest 的集成:响应出站网关的空有效负载
【发布时间】:2016-11-26 10:37:57
【问题描述】:

我正在使用 Spring Integration 和 <int-http:outbound-gateway> 调用 Spring Data Rest URL。

我的调用是一个简单的HTTP GET,指向一个已知的资源 URL(在我的例子中是“示例”)。

这是<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>

在日志中我可以看到这条消息:

“extractPayload”属性与当前无关 请求,因为 HTTP 方法是 'GET',并且没有请求正文 发送该方法。

我想这是指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]
}>

但是,我不明白为什么“有效负载正文”为空,正如您在 Content-Length 标头中看到的那样。

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 好像是空的。

有没有办法通过出站网关获得与 HTTP 相同的 JSON 结果?

提前致谢。

更新

按照 Gary 的建议,我已经监控了流量。

这里是请求的详细信息:

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

请求似乎是相同的,除了一个标头(Cookie JSESSIONID,在集成上下文中不存在)。

更新 2

也许我已经找到了响应中空负载的原因。

org.springframework.web.client.RestTemplate 的 "extractData" 方法将对象实例 this.delegate 设置为 null 值。

因此,作为回报,有一个ResponseEntity 对象没有主体。

@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 会很有趣。

【问题讨论】:

  • 请求中可能有些不同之处。我建议您使用 TCP 监视器(eclipse 内置一个,或使用 wireshark 等)来比较两个请求/响应。如果您无法从中弄清楚,请使用网络跟踪编辑问题。
  • 感谢您的建议,加里。我已经用请求的详细信息编辑了问题。
  • 听起来你的服务器应用可能需要一个会话(登录?)——你需要在服务器端进行调试。
  • 我已经添加了第二次更新,也许我已经找到了问题的原因,但我不知道如何解决它!
  • 在下面查看我的答案 - 如果您在之前的编辑中显示回复和请求,我们可以更快地到达这里。

标签: spring spring-integration spring-data-rest


【解决方案1】:

您需要将expected-response-type="java.lang.String"添加到网关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    相关资源
    最近更新 更多