当前位置: 首页 > 知识库问答 >
问题:

REST模板:HttpMessageNotWritableExcture:没有找到类java.io.ByteArrayInputStream的序列化程序

能文华
2023-03-14

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

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

我不明白的是,为什么调用RestTemplate时会出现下面的异常。交易所()

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个答案

云宏儒
2023-03-14

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

看来你需要提取文件内容

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

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

 类似资料: