问题
We've been experiencing this weird problem with the request Host header being set as the application's URL. This results to the external system to not handle our requests.
Here's the DEBUG log of apache of the Spring Integration application
hosted on localhost:8082
. Don't mind the content for now but the Content-Type will be a problem subsequently:
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]"
and here's the request done with 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)
So with Spring Integration
org.apache.http.wire - http-outgoing-0 >> "host: localhost:8082[\r][\n]"
and with curl
> Host: localhost:9292
We can easily solve the host
problem in Spring Integration by setting the header mapper of the outgate:
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"
So we were able to solve the problem with the Host
header, unfortunately, it seems that the Content-Type
set through an enricher has been ignored and has been set to text/plain
instead of application/xml
.
What seems to be the problem here? I'm assuming this has to do with just using a basic DefaultHttpHeaderMapper.
Here's the flow configuration snippet:
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());
}
}
回答1:
Use
DefaultHttpHeaderMapper mapper = DefaultHttpHeaderMapper.outboundMapper();
mapper.setExcludedOutboundStandardRequestHeaderNames(new String[] { "Host" });
handler.setHeaderMapper(mapper);
来源:https://stackoverflow.com/questions/44908154/spring-integration-wrong-host-header