问题描述
使用Spring Integration,我通过HTTP POST上传文件,并将其路由到服务激活器.
Using Spring Integration I upload a file via HTTP POST and route it to a service activator.
在服务激活器中,我使用RestTemplate调用了另一个将文件转储到其中的服务器,但是我无法弄清楚为什么以下代码会出现以下错误:
In the service activator, I make a call using RestTemplate to another server where to dump the file but I can't figure out why I get the following error for the following code:
我不明白的是为什么我在调用RestTemplate.exchange()时出现下面的异常
What I don't understand is why I get the exception below when I call 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-config
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="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
bean used by service activator
@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
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);
}
推荐答案
问题是您要将完整的UploadedMultipartFile
对象传递给RestTemplate
.杰克逊(Jackson)试图序列化该对象,包括它不能包含的inputStream
属性.
The problem is you are passing the complete UploadedMultipartFile
object to the RestTemplate
. Jackson is trying to serialize the object, including the inputStream
property, which it cannot.
似乎您需要提取文件内容
It appears you need to extract the file contents
byte[] bytes ((UploadedMultipartFile) multipartRequest.getFirst("file")).getBytes();
并将内容类型设置为UploadedMultipartFile.getContentType()
.
这篇关于Resttemplate:HttpMessageNotWritableException:未找到类java.io.ByteArrayInputStream的序列化程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!