spring integration inbound gateway http request he

2019-02-20 03:47发布

问题:

I have files stored in MongoDB which can be uploaded/downloaded/deleted via a Rest service. I'd like to download files from MongoDB via Spring Integration (+Boot+Embedded Jetty) but I can't figure out how to set the Content-Disposition header properly because the downloaded file has the correct payload but the filename is wrong (it's receiveGateway without any extension):

xml config

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:int="http://www.springframework.org/schema/integration"
       xmlns:int-http="http://www.springframework.org/schema/integration/http"
       xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd">

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- one of the properties available; the maximum file size in bytes -->
    <property name="maxUploadSize" value="100000"/>
</bean>

<bean id="byteArrayHttpMessageConverter"
      class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
</bean>

<int:channel id="http.frontend.rx"/>
<int:channel id="http.frontend.tx"/>
<int:channel id="http.backend.mysql.api.rx"/>
<int:channel id="http.backend.mysql.api.tx"/>
<int:channel id="http.backend.mongodb.api.rx"/>
<int:channel id="http.backend.mongodb.api.tx"/>
<!-- -->
<int-http:inbound-gateway
    id="frontEndToFlow"
    request-channel="http.frontend.rx"
    reply-channel="http.frontend.tx"
    path="/receiveGateway"
    mapped-request-headers="*"
    mapped-response-headers="Content-Disposition,Content-Length,Content-Type,Server,Application-Context,Content-Transfer-Encoding"
    message-converters="byteArrayHttpMessageConverter"
    supported-methods="GET,POST,PUT,DELETE"/>
<int-http:outbound-gateway
    id="FlowToBackEnd"
    request-channel="http.backend.mysql.api.tx"
    reply-channel="http.backend.mysql.api.rx"
    url="http://localhost:7070/api/{path}"
    http-method-expression="headers.http_requestMethod"
    expected-response-type="java.lang.String"
    charset="UTF-8">
    <int-http:uri-variable name="path" expression="'users/user@gmail.com/'"/>
</int-http:outbound-gateway>
<int-http:outbound-gateway
    id="springFlowToHttpBackEndMongoDB"
    request-channel="http.backend.mongodb.api.tx"
    reply-channel="http.backend.mongodb.api.rx"
    url="http://localhost:5050/api/{path}"
    http-method-expression="headers.http_requestMethod"
    message-converters="byteArrayHttpMessageConverter"
    mapped-request-headers="*"
    mapped-response-headers="Content-Disposition,Content-Length,Content-Type,Server,X-Application-Context,Content-Transfer-Encoding"
    expected-response-type="byte[]"
    charset="UTF-8">
    <int-http:uri-variable name="path" expression="'download/53cffb7c6c29a4f718627905'"/>
</int-http:outbound-gateway>
<int:service-activator
    id="inboundServiceActivator"
    input-channel="http.frontend.rx"
    output-channel="http.backend.mongodb.api.tx"
    ref="messageReaderService"
    method="printContent">
</int:service-activator>
<int:service-activator
    id="outboundServiceActivator"
    input-channel="http.backend.mongodb.api.rx"
    output-channel="http.frontend.tx"
    ref="messageReaderService"
    method="printContent">
</int:service-activator>

http request/response headers

Remote Address:::1:8080
Request URL:http://localhost:8080/receiveGateway
Request Method:GET
Status Code:200 OK
Request Headersview source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,ro;q=0.6,nb;q=0.4
Connection:keep-alive
Cookie:m=1933:86400%7C1800|2377:small|2491:chart|3247:t|34e2:|47ba:t|1d98:t|2a03:t|745a:t|77cb:t|5cf4:t|ca3:t|54e1:t|4e71:small|e69:chart|45b9:86400%7C1800|4a01:t|4c1b:t|3eff:t; JSESSIONID=8ACC161B9338DC122564C8BAB81EF25D
DNT:1
Host:localhost:8080
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
Response Headersview source
Content-Length:33331
Content-Type:application/octet-stream
Server:Jetty(8.1.15.v20140411)
X-Content-Disposition:attachment; filename="aqmAR47_460s.jpg"

Application.java

@Configuration
@ComponentScan
@EnableAutoConfiguration
@ImportResource("classpath:httpgateway.xml")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

MessageReaderService.java - used it to see headers ... which are correct ...

@Component
public class MessageReaderService {

    public Message printContent(Message message){
        System.out.println(message.getHeaders().toString());
        return message;
    }

}

System.out.println console output

    {errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@2f53f6f3, http_requestMethod=GET, Cookie=m=1933:86400%7C1800|2377:small|2491:chart|3247:t|34e2:|47ba:t|1d98:t|2a03:t|745a:t|77cb:t|5cf4:t|ca3:t|54e1:t|4e71:small|e69:chart|45b9:86400%7C1800|4a01:t|4c1b:t|3eff:t; JSESSIONID=8ACC161B9338DC122564C8BAB81EF25D, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@2f53f6f3, Host=localhost:8080, User-Agent=Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36, http_requestUrl=http://localhost:8080/receiveGateway, Connection=keep-alive, Accept-Language=en-US,en;q=0.8,ro;q=0.6,nb;q=0.4, Accept-Encoding=gzip,deflate,sdch, DNT=1, Accept=[text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8], id=a5c4630e-f064-7245-8c8d-9e6706c361af, timestamp=1406907105217}
2014-08-01 18:31:45.218  WARN 8364 --- [qtp699466412-13] o.s.i.h.support.DefaultHttpHeaderMapper  : Header 'X-errorChannel' with value 'org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@2f53f6f3' will not be set since it is not a String and no Converter is available. Consider registering a Converter with ConversionService (e.g., <int:converter>)
2014-08-01 18:31:45.218  WARN 8364 --- [qtp699466412-13] o.s.i.h.support.DefaultHttpHeaderMapper  : Header 'X-replyChannel' with value 'org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@2f53f6f3' will not be set since it is not a String and no Converter is available. Consider registering a Converter with ConversionService (e.g., <int:converter>)
2014-08-01 18:31:45.218  WARN 8364 --- [qtp699466412-13] o.s.i.h.support.DefaultHttpHeaderMapper  : Header 'X-id' with value 'a5c4630e-f064-7245-8c8d-9e6706c361af' will not be set since it is not a String and no Converter is available. Consider registering a Converter with ConversionService (e.g., <int:converter>)
2014-08-01 18:31:45.219  WARN 8364 --- [qtp699466412-13] o.s.i.h.support.DefaultHttpHeaderMapper  : Header 'X-timestamp' with value '1406907105217' will not be set since it is not a String and no Converter is available. Consider registering a Converter with ConversionService (e.g., <int:converter>)
{errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@2f53f6f3, http_requestMethod=GET, Cookie=m=1933:86400%7C1800|2377:small|2491:chart|3247:t|34e2:|47ba:t|1d98:t|2a03:t|745a:t|77cb:t|5cf4:t|ca3:t|54e1:t|4e71:small|e69:chart|45b9:86400%7C1800|4a01:t|4c1b:t|3eff:t; JSESSIONID=8ACC161B9338DC122564C8BAB81EF25D, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@2f53f6f3, Host=localhost:8080, Content-Length=33331, User-Agent=Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36, http_requestUrl=http://localhost:8080/receiveGateway, Connection=keep-alive, Server=Jetty(8.1.15.v20140411), Accept-Language=en-US,en;q=0.8,ro;q=0.6,nb;q=0.4, Content-Disposition=attachment; filename="aqmAR47_460s.jpg", http_statusCode=200, Accept-Encoding=gzip,deflate,sdch, DNT=1, Content-Type=application/octet-stream, X-Application-Context=application:5050, Accept=[text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8], id=4c1f52c8-b5f7-067c-2d60-826242d9d2db, timestamp=1406907105236}
{errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@6105c7d8, http_requestMethod=GET, Cookie=m=1933:86400%7C1800|2377:small|2491:chart|3247:t|34e2:|47ba:t|1d98:t|2a03:t|745a:t|77cb:t|5cf4:t|ca3:t|54e1:t|4e71:small|e69:chart|45b9:86400%7C1800|4a01:t|4c1b:t|3eff:t; JSESSIONID=8ACC161B9338DC122564C8BAB81EF25D, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@6105c7d8, Host=localhost:8080, User-Agent=Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36, http_requestUrl=http://localhost:8080/receiveGateway, Connection=keep-alive, Accept-Language=en-US,en;q=0.8,ro;q=0.6,nb;q=0.4, Accept-Encoding=gzip,deflate,sdch, DNT=1, Accept=[text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8], id=21994eda-55aa-c798-53bc-c406e53e878d, timestamp=1406907106040}
2014-08-01 18:31:46.041  WARN 8364 --- [qtp699466412-14] o.s.i.h.support.DefaultHttpHeaderMapper  : Header 'X-errorChannel' with value 'org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@6105c7d8' will not be set since it is not a String and no Converter is available. Consider registering a Converter with ConversionService (e.g., <int:converter>)
2014-08-01 18:31:46.042  WARN 8364 --- [qtp699466412-14] o.s.i.h.support.DefaultHttpHeaderMapper  : Header 'X-replyChannel' with value 'org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@6105c7d8' will not be set since it is not a String and no Converter is available. Consider registering a Converter with ConversionService (e.g., <int:converter>)
2014-08-01 18:31:46.043  WARN 8364 --- [qtp699466412-14] o.s.i.h.support.DefaultHttpHeaderMapper  : Header 'X-id' with value '21994eda-55aa-c798-53bc-c406e53e878d' will not be set since it is not a String and no Converter is available. Consider registering a Converter with ConversionService (e.g., <int:converter>)
2014-08-01 18:31:46.043  WARN 8364 --- [qtp699466412-14] o.s.i.h.support.DefaultHttpHeaderMapper  : Header 'X-timestamp' with value '1406907106040' will not be set since it is not a String and no Converter is available. Consider registering a Converter with ConversionService (e.g., <int:converter>)
{errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@6105c7d8, http_requestMethod=GET, Cookie=m=1933:86400%7C1800|2377:small|2491:chart|3247:t|34e2:|47ba:t|1d98:t|2a03:t|745a:t|77cb:t|5cf4:t|ca3:t|54e1:t|4e71:small|e69:chart|45b9:86400%7C1800|4a01:t|4c1b:t|3eff:t; JSESSIONID=8ACC161B9338DC122564C8BAB81EF25D, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@6105c7d8, Host=localhost:8080, Content-Length=33331, User-Agent=Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36, http_requestUrl=http://localhost:8080/receiveGateway, Connection=keep-alive, Server=Jetty(8.1.15.v20140411), Accept-Language=en-US,en;q=0.8,ro;q=0.6,nb;q=0.4, Content-Disposition=attachment; filename="aqmAR47_460s.jpg", http_statusCode=200, Accept-Encoding=gzip,deflate,sdch, DNT=1, Content-Type=application/octet-stream, X-Application-Context=application:5050, Accept=[text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8], id=a048606a-f03f-89d8-e981-bb661bc7e955, timestamp=1406907106058}

回答1:

Good. I see now.

First of all: please, raise, an improvement JIRA issue (https://jira.spring.io/browse/INT): Content-Disposition is really a standard HTTP header and have to map it by default.

Right now you can overcome it with injected DefaultHttpHeaderMapper instead of those mapped-request-headers and mapped-response-headers. In addition you have to configure setUserDefinedHeaderPrefix as null.

It is X- by default, so we should change it to populate Content-Disposition.

Thank you for pointing it out!