Spring integration Resttemplate:HttpMessageNotWritableException:未找到类java.io.ByteArrayInputStream的序列化程序

Spring integration Resttemplate:HttpMessageNotWritableException:未找到类java.io.ByteArrayInputStream的序列化程序,spring-integration,multipart,Spring Integration,Multipart,使用SpringIntegration,我通过HTTPPOST上传一个文件,并将其路由到服务激活器 在service activator中,我使用RestTemplate调用另一台服务器,在那里转储文件,但我不明白为什么以下代码会出现以下错误: 我不明白的是,为什么调用restemplate.exchange()时会出现以下异常 xml配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sprin

使用SpringIntegration,我通过HTTPPOST上传一个文件,并将其路由到服务激活器

在service activator中,我使用RestTemplate调用另一台服务器,在那里转储文件,但我不明白为什么以下代码会出现以下错误:

我不明白的是,为什么调用restemplate.exchange()时会出现以下异常

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);

    }

}
@组件
公共类多部件接收器{
public void printMultiPartContent(LinkedMultiValueMap multipartRequest){
System.out.println(“####成功接收到多部分请求###”);
for(String elementName:multipartRequest.keySet()){
if(elementName.equals(“文件”)){
System.out.println(“\t”+elementName+”-作为上载的MultipartFile:“+
((UploadedMultipartFile)multipartRequest
.getFirst(“文件”).getOriginalFilename();
}
}
RestTemplate=新的RestTemplate();
字符串uri=”http://localhost:5050/api/upload";
MultiValueMap=新链接的MultiValueMap();
map.add(“文件”,multipartRequest.getFirst(“文件”);
HttpHeaders=新的HttpHeaders();
headers.set(“内容类型”、“多部分/表单数据”);
HttpEntity请求=新的HttpEntity(映射、头);
ResponseEntity response=template.exchange(uri,HttpMethod.POST,请求,字节[].class);
}
}
stacktrace::

工作代码::

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);

    }
public void printMultiPartContent(LinkedMultiValueMap multipartRequest)引发IOException{
最终字符串文件名=((UploadedMultipartFile)multipartRequest.getFirst(“文件”)).getOriginalFilename();
RestTemplate=新的RestTemplate();
MultiValueMap multipartMap=新链接的MultiValueMap();
添加(“名称”,文件名);
添加(“文件名”,文件名);
字节[]字节=((UploadedMultipartFile)multipartRequest.getFirst(“文件”)).getBytes();
ByteArrayResource内容资源=新的ByteArrayResource(字节){
公共字符串getFilename(){
返回文件名;
}
};
multipartMap.add(“文件”,contentsAsResource);
字符串结果=模板。postForObject(“http://localhost:5050/api/upload,多部分映射,字符串.class);
系统输出打印项次(结果);
}

问题是您正在将完整的
UploadedMultipartFile
对象传递给
RestTemplate
。Jackson正在尝试序列化对象,包括它无法序列化的
inputStream
属性

似乎您需要提取文件内容

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

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

您可能应该只发送字节[]而不是映射。今天进行了一些测试,试图将文件作为字节数组发送,但另一端收到400个错误请求。。。如果我用cUrl或RestConsole进行测试,效果很好。。。我将重新测试并发回更多详细信息…第四个答案看起来很有希望-可能从字节[]创建一个
ByteArrayResource
。您的工作代码应该包含在答案中。
byte[] bytes ((UploadedMultipartFile) multipartRequest.getFirst("file")).getBytes();