我们一直在将请求 Host 标头设置为应用程序的 URL 时遇到这个奇怪的问题。这导致外部系统无法处理我们的请求。
这是Spring Integration application
托管在apache 上的调试日志localhost:8082
。现在不要介意内容,但 Content-Type 随后将成为问题:
org.apache.http.wire - http-outgoing-0 >> "POST /health HTTP/1.1[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Accept: */*[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "cookie: PHPSESSID=ost897ibh0j7rovf2rudr33c22[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "host: localhost:8082[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "connection: keep-alive[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Cache-Control: no-cache[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Content-Type: application/xml[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "accept-encoding: gzip, deflate[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "user-agent: PostmanRuntime/6.1.6[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Content-Length: 4[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "test"
org.apache.http.wire - http-outgoing-0 << "HTTP/1.1 200 OK[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "Content-Type: application/json[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "Transfer-Encoding: chunked[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "Server: Jetty(9.2.z-SNAPSHOT)[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "27[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "{"success":true,"message":"Service up"}"
org.apache.http.headers - http-outgoing-0 << HTTP/1.1 200 OK
org.apache.http.headers - http-outgoing-0 << Content-Type: application/json
org.apache.http.headers - http-outgoing-0 << Transfer-Encoding: chunked
org.apache.http.headers - http-outgoing-0 << Server: Jetty(9.2.z-SNAPSHOT)
org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "0[\r][\n]"
org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
这是使用 curl 完成的请求:
curl -v -X POST http://localhost:9292/health
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 9292 (#0)
> POST /health HTTP/1.1
> Host: localhost:9292
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Transfer-Encoding: chunked
< Server: Jetty(9.2.z-SNAPSHOT)
所以使用 Spring 集成
org.apache.http.wire - http-outgoing-0 >> "host: localhost:8082[\r][\n]"
和卷曲
> Host: localhost:9292
我们可以host
通过设置 outgate 的 header mapper 轻松解决 Spring Integration 中的问题:
handler.setHeaderMapper(new DefaultHttpHeaderMapper());
org.apache.http.wire - http-outgoing-0 >> "POST /health HTTP/1.1[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Accept: application/json, application/*+json[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Content-Type: text/plain;charset=UTF-8[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Content-Length: 4[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Host: localhost:9292[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_112)[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "[\r][\n]"
org.apache.http.wire - http-outgoing-0 >> "test"
所以我们能够解决Host
标题的问题,不幸的是,似乎Content-Type
通过浓缩器设置的设置已被忽略并设置为text/plain
而不是application/xml
.
这里似乎有什么问题?我假设这与使用基本的 DefaultHttpHeaderMapper 有关。
这是流程配置片段:
public class BasicIntegrationConfig {
@Bean
public MessageChannel basicRequestChannel() {
return MessageChannels.publishSubscribe().get();
}
@Bean
public MessageChannel basicResponseChannel() {
return MessageChannels.publishSubscribe().get();
}
@Bean
public MessagingGatewaySupport basicInGate() {
HttpRequestHandlingMessagingGateway handler = new HttpRequestHandlingMessagingGateway();
RequestMapping mapping = new RequestMapping();
mapping.setPathPatterns("api/v1/basic");
mapping.setMethods(HttpMethod.GET);
mapping.setProduces(MediaType.APPLICATION_JSON_UTF8_VALUE);
handler.setRequestMapping(mapping);
handler.setRequestChannel(basicRequestChannel());
handler.setReplyChannel(basicResponseChannel());
return handler;
}
@Bean
public MessageHandler basicOutGate() {
HttpRequestExecutingMessageHandler handler =
new HttpRequestExecutingMessageHandler("http://localhost:9292/health");
handler.setHttpMethod(HttpMethod.POST);
handler.setExpectedResponseType(BaseResponse.class);
handler.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
handler.setHeaderMapper(new DefaultHttpHeaderMapper());
return handler;
}
@Bean
public IntegrationFlow basicFlow() {
return (IntegrationFlowDefinition<?> f) -> f
.channel(basicRequestChannel())
.log("basic")
.handle((GenericHandler<Object>) (o, map) -> "test")
.enrichHeaders(e -> e.header(MessageHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE, true))
.log("basic")
.handle(basicOutGate())
.log("basic")
.enrichHeaders(e -> e.header(MessageHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE, true))
.channel(basicResponseChannel());
}
}