Resttemplate:HttpMessageNotWritableException:没有为类java.io.ByteArrayInputStream找到序列化程序

时间:2014-08-03 08:50:47

标签: spring-integration multipart

使用Spring集成我通过HTTP POST上传文件并将其路由到服务激活器。

在服务激活器中,我使用RestTemplate调用另一个服务器来转储文件,但我无法弄清楚为什么我会收到以下代码的以下错误:

我不明白为什么在调用RestTemplate.exchange()

时会出现以下异常的原因
at pdi.integration.MultipartReceiver.printMultiPartContent(MultipartReceiver.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)

XML的配置

<?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="byteArrayHttpMessageConverter"
          class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
    </bean>

    <bean id="formHttpMessageConverter"
          class="org.springframework.http.converter.FormHttpMessageConverter">
    </bean>

    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

    <bean id="headerMapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
        <property name="inboundHeaderNames" value="*"/>
        <property name="outboundHeaderNames" value="*"/>
        <property name="userDefinedHeaderPrefix" value=""/>
    </bean>

    <int:channel id="http.frontend.rx"/>
    <int:channel id="http.frontend.tx"/>
    <int:channel id="http.backend.mysql.rx"/>
    <int:channel id="http.backend.mysql.tx"/>
    <int:channel id="http.backend.mongo.rx"/>
    <int:channel id="http.backend.mongo.tx"/>
    <int:channel id="http.backend.file.tx"/>

    <int-http:inbound-gateway
            id="frontEndToMySQLXX"
            request-channel="http.frontend.rx"
            reply-channel="http.frontend.tx"
            header-mapper="headerMapper"
            path="/gateway"
            supported-methods="GET,POST,PUT,DELETE"/>

    <int:router id="frontEndRouter" input-channel="http.frontend.rx" expression="headers.service">
        <int:mapping value="json" channel="http.backend.mysql.tx" />
        <int:mapping value="file" channel="http.backend.mongo.tx" />
        <int:mapping value="upload" channel="http.backend.file.tx" />
    </int:router>

    <!-- removed : message-converters="formHttpMessageConverter,byteArrayHttpMessageConverter" -->
    <int-http:outbound-gateway
            id="toMongoDB"
            request-channel="http.backend.mongo.tx"
            reply-channel="http.backend.mongo.rx"
            url="http://localhost:5050/api/{path}"
            http-method-expression="headers.http_requestMethod"
            header-mapper="headerMapper"
            expected-response-type="byte[]">
        <int-http:uri-variable name="path" expression="headers['urlpath']"/>
    </int-http:outbound-gateway>

    <int-http:outbound-gateway
            id="toMySQLDB"
            request-channel="http.backend.mysql.tx"
            reply-channel="http.backend.mysql.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="headers['urlpath']"/>
    </int-http:outbound-gateway>

    <int:service-activator
        id="MySQLToFrontEnd"
        input-channel="http.backend.mysql.rx"
        output-channel="http.frontend.tx"
        ref="messageService"
        method="printContent">
    </int:service-activator>

    <int:service-activator
        id="MongoToFrontEnd"
        input-channel="http.backend.file.tx"
        output-channel="http.frontend.tx"
        ref="multipartReceiver"
        method="printMultiPartContent">
    </int:service-activator>

 </beans>

服务激活器使用的bean

@Component
public class MultipartReceiver {

    public void printMultiPartContent(LinkedMultiValueMap<String, Object> multipartRequest){

        System.out.println("### Successfully received multipart request ###");
        for (String elementName : multipartRequest.keySet()) {
            if (elementName.equals("file")){
                System.out.println("\t" + elementName + " - as UploadedMultipartFile: " +
                        ((UploadedMultipartFile) multipartRequest
                                .getFirst("file")).getOriginalFilename());
            }
        }

        RestTemplate template = new RestTemplate();
        String uri = "http://localhost:5050/api/upload";
        MultiValueMap map = new LinkedMultiValueMap<String,Object>();
        map.add("file", multipartRequest.getFirst("file"));
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "multipart/form-data");
        HttpEntity request = new HttpEntity(map, headers);
        ResponseEntity<byte[]> response = template.exchange(uri, HttpMethod.POST, request, byte[].class);

    }

}

stacktrace :: http://pastebin.com/5Wa9VaRb

工作代码::

public void printMultiPartContent(LinkedMultiValueMap<String, Object> multipartRequest) throws IOException {

        final String filename = ((UploadedMultipartFile) multipartRequest.getFirst("file")).getOriginalFilename();

        RestTemplate template = new RestTemplate();
        MultiValueMap<String, Object> multipartMap = new LinkedMultiValueMap<String, Object>();
        multipartMap.add("name", filename);
        multipartMap.add("filename", filename);

        byte[] bytes = ((UploadedMultipartFile) multipartRequest.getFirst("file")).getBytes();
        ByteArrayResource contentsAsResource = new ByteArrayResource(bytes){
            public String getFilename(){
                return filename;
            }
        };

        multipartMap.add("file", contentsAsResource);
        String result = template.postForObject("http://localhost:5050/api/upload", multipartMap, String.class);
        System.out.println(result);

    }

1 个答案:

答案 0 :(得分:2)

问题是您将完整的UploadedMultipartFile对象传递给RestTemplate。杰克逊试图序列化对象,包括inputStream属性,但它不能。

您似乎需要提取文件内容

byte[] bytes ((UploadedMultipartFile) multipartRequest.getFirst("file")).getBytes();

并将内容类型设置为UploadedMultipartFile.getContentType()

相关问题