Spring http出站网关 - 如何使用正文返回ResponseEntity

时间:2015-06-03 12:54:34

标签: java spring http spring-integration

我可能会用这个咆哮错误的树,但我在Spring Integration和http出站网关方面遇到了一些困难。

我可以对其进行配置,使其生成http POST,并将响应正文设为简单的String,如下所示:

Spring配置

<int-http:outbound-gateway request-channel="hotelsServiceGateway.requestChannel"
                           reply-channel="hotelsServiceGateway.responseChannel"
                           url="http://api.ean.com/ean-services/rs/hotel/v3/list"
                           expected-response-type="java.lang.String"
                           http-method="POST"/>

接口

public interface ExpediaHotelsService {
    String getHotelsList(final Map<String, String> parameters);
}

我可以对其进行配置,以便我得到ResponseEntity这样的回复:

Spring配置

<int-http:outbound-gateway request-channel="hotelsServiceGateway.requestChannel"
                           reply-channel="hotelsServiceGateway.responseChannel"
                           url="http://api.ean.com/ean-services/rs/hotel/v3/list"
                           http-method="POST"/>

接口

public interface ExpediaHotelsService {
    ResponseEntity<String> getHotelsList(final Map<String, String> parameters);
}

两个版本的代码都有效。但是,当返回String时,我得到了响应正文,但我没有得到http状态和标题等 但是当我使用ResponseEntity版本时,我会获得http状态和标题,但我总是通过ResponseEntity#getBody得到一个空身

无论如何,我可以同时获得正文和http状态以及标题吗? (忽略expedia酒店api返回JSON的事实 - 目前我只想获取原始文本)

<小时/> 一些进一步的信息有助于澄清我所看到的问题。如果我在响应通道上点击一下:

当我将其配置为返回一个简单的String时,我得到:
INFO: GenericMessage [payload={"HotelListResponse":{"EanWsError":{"itineraryId":-1,"handling":"RECOVERABLE","category":"AUTHENTICATION","exceptionConditionId":-1,"presentationMessage":"TravelNow.com cannot service this request.","verboseMessage":"Authentication failure. (cid=0; ipAddress=194.73.101.79)"},"customerSessionId":"2c9d7b43-3447-4b5e-ad87-54ce7a810041"}}, headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@4d0f2471, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@4d0f2471, Server=EAN, Connection=keep-alive, id=5e3cb978-9730-856e-1583-4a0847b8dc73, Content-Length=337, contentType=application/json, http_statusCode=200, Date=1433403827000, Content-Type=application/x-www-form-urlencoded, timestamp=1433403827133}]
您可以在有效负载中看到完整的响应正文,并注意Content-Length设置为337

相反,当我使用ResponseEntity<String>时,我得到:
INFO: GenericMessage [payload=<200 OK,{Transaction-Id=[5f3894df-0a8e-11e5-a43a-ee6fbd565000], Content-Type=[application/json], Server=[EAN], Date=[Thu, 04 Jun 2015 07:50:30 GMT], Content-Length=[337], Connection=[keep-alive]}>, headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@4d0f2471, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@4d0f2471, Server=EAN, Connection=keep-alive, id=9a598432-99c9-6a15-3451-bf9b1515491b, Content-Length=337, contentType=application/json, http_statusCode=200, Date=1433404230000, Content-Type=application/x-www-form-urlencoded, timestamp=1433404230465}]
Content-Length仍然设置为337,但有效负载中没有响应正文

1 个答案:

答案 0 :(得分:0)

请注意,对于第二种情况,您不使用任何expected-response-type

如果没有RestTemplate,则expected-response-type会以这种方式运作:

public ResponseEntityResponseExtractor(Type responseType) {
        if (responseType != null && !Void.class.equals(responseType)) {
            this.delegate = new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);
        }
        else {
            this.delegate = null;
        }
    }

    @Override
    public ResponseEntity<T> extractData(ClientHttpResponse response) throws IOException {
        if (this.delegate != 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());
        }
    }

如您所见,它确实会返回ResponseEntity而不是body。 Spring Integration在此事上无能为力......

从另一方面看看你是否真的需要一个完整的ResponseEntity作为<int-http:outbound-gateway>的回复。 也许headerMapper对您来说已经足够了?..例如,http status已经存在,即使在问题的日志中也是如此:

  

Server = EAN,Connection = keep-alive,id = 5e3cb978-9730-856e-1583-4a0847b8dc73,Content-Length = 337,contentType = application / json,http_statusCode = 200,Date = 1433403827000,Content-Type = application / X WWW的窗体-urlencoded,