Java 多部分请求未按spring集成的预期工作
我有两个rest服务和一个侦听器Java 多部分请求未按spring集成的预期工作,java,spring-integration,spring-integration-http,Java,Spring Integration,Spring Integration Http,我有两个rest服务和一个侦听器 服务A 服务B 监听器L1 步骤1-侦听器L1从本地读取文件并发送多值 映射到服务A。服务A从数据库中检索一些文档并 将其作为字节返回给侦听器L1。 步骤2-侦听器L1然后发送 另一个多值映射到服务B并保存文档 步骤1使用MultiValueMap按预期工作,其中,当我尝试使用相同的过程将文档字节发送到服务B时 在第2步中- 我得到无法写入请求:找不到适合请求类型[org.springframework.util.LinkedMultiValueMap
- 步骤1-侦听器L1从本地读取文件并发送多值
映射到服务A。服务A从数据库中检索一些文档并
将其作为字节返回给侦听器L1。
步骤2-侦听器L1然后发送 另一个多值映射到服务B并保存文档
步骤1使用MultiValueMap按预期工作,其中,当我尝试使用相同的过程将文档字节发送到服务B时 在第2步中- 我得到无法写入请求:找不到适合请求类型[org.springframework.util.LinkedMultiValueMap]和内容类型[application/octet stream]的HttpMessageConverter。我遵循同样的程序,但仍然得到问题 请查找下面的代码示例,并让我知道如何解决此问题 Listener1.java
public Message<?> processJMSReqMsqAndSendToRest1(String message) throws Exception {
MultiValueMap<String, Object> mainMap = new LinkedMultiValueMap<String, Object>();
Map<String, String> secondaryMap = new HashMap<String, String>();
secondaryMap.put("key1", "value1");
secondaryMap.put("key2", "value2");
secondaryMap.put("key3", "value3");
byte[] messageBytes = message.getBytes();
File newFile = new File("D:\\Temp\\temp.jpg");
InputStream is = new FileInputStream(newFile);
byte[] fileBytes = IOUtils.toByteArray(is);
is.close();
mainMap.add("metaData", secondaryMap);
mainMap.add("messageBytes", messageBytes );
Message<?> message1 = MessageBuilder.withPayload(mainMap).build();
return message1;
}
public Message<?> processRest1AndSendToRest2(Message<?> obj) throws Exception{
byte[] docBytes = (byte[])obj.getPayload();
MultiValueMap<String, Object> mainMap = new LinkedMultiValueMap<String, Object>();
Map<String, String> secondaryMap = new HashMap<String, String>();
secondaryMap.put("key1", "value1");
secondaryMap.put("key2", "value2");
secondaryMap.put("key3", "value3");
mainMap.add("metaData", secondaryMap);
mainMap.add("messageBytes", docBytes);
Message<?> message1 = MessageBuilder.withPayload(mainMap).build();
return message1;
公共消息进程JMSREQMSQandSendToRest1(字符串消息)引发异常{
MultiValueMap mainMap=新链接的MultiValueMap();
Map secondaryMap=新的HashMap();
二次映射放置(“键1”、“值1”);
二次映射。放置(“键2”、“值2”);
二次映射放置(“键3”、“值3”);
byte[]messageBytes=message.getBytes();
File newFile=新文件(“D:\\Temp\\Temp.jpg”);
InputStream is=新文件InputStream(新文件);
byte[]fileBytes=IOUtils.toByteArray(is);
is.close();
添加(“元数据”,第二地图);
mainMap.add(“messageBytes”,messageBytes);
message1=MessageBuilder.withPayload(mainMap.build();
返回消息1;
}
公共消息ProcessRest1和SendToRest2(消息obj)引发异常{
字节[]docBytes=(字节[])obj.getPayload();
MultiValueMap mainMap=新链接的MultiValueMap();
Map secondaryMap=新的HashMap();
二次映射放置(“键1”、“值1”);
二次映射。放置(“键2”、“值2”);
二次映射放置(“键3”、“值3”);
添加(“元数据”,第二地图);
mainMap.add(“messageBytes”,docBytes);
message1=MessageBuilder.withPayload(mainMap.build();
返回消息1;
}
Spring集成xml
<int-http:outbound-gateway
id="docServiceOutBoundGateway" request-channel="docMetaDataIn"
http-method="POST" url="http://localhost:8030/getDocument"
expected-response-type="[B" reply-channel="sourceDocumentOutLv1">
</int-http:outbound-gateway>
<int:service-activator
input-channel="sourceDocumentOutLv1"
ref="docConversionOrchestratorImpl" method="processRest1AndSendToRest2"
output-channel="sourceDocumentOutLv2" />
<int-http:outbound-gateway request-channel="sourceDocumentOutLv2"
http-method="POST" url="http://localhost:8030/sendDocument"
encode-uri="false"
expected-response-type="java.lang.String" reply-channel="processedDocOutLv1">
</int-http:outbound-gateway>
服务A:
@RequestMapping(value = "/getDocument", method = RequestMethod.POST)
@ResponseBody
public byte[] testRest1(@RequestPart("metaData")Map<String,String> metaData,@RequestPart("messageBytes")byte[] messageBytes) {
byte[] r2 = //get doc from database as bytes
return r2;
}
@RequestMapping(value = "/sendDocument", method = RequestMethod.POST)
@ResponseBody
public String tesMySql1(@RequestPart("metaData")Map<String,String> metaData,@RequestPart("messageBytes")byte[] messageBytes) {
return "working";
}
@RequestMapping(value=“/getDocument”,method=RequestMethod.POST)
@应答器
公共字节[]testRest1(@RequestPart(“metaData”)映射元数据,@RequestPart(“messageBytes”)字节[]messageBytes){
byte[]r2=//以字节形式从数据库获取文档
返回r2;
}
服务B:
@RequestMapping(value = "/getDocument", method = RequestMethod.POST)
@ResponseBody
public byte[] testRest1(@RequestPart("metaData")Map<String,String> metaData,@RequestPart("messageBytes")byte[] messageBytes) {
byte[] r2 = //get doc from database as bytes
return r2;
}
@RequestMapping(value = "/sendDocument", method = RequestMethod.POST)
@ResponseBody
public String tesMySql1(@RequestPart("metaData")Map<String,String> metaData,@RequestPart("messageBytes")byte[] messageBytes) {
return "working";
}
@RequestMapping(value=“/sendDocument”,method=RequestMethod.POST)
@应答器
公共字符串tesMySql1(@RequestPart(“元数据”)映射元数据,@RequestPart(“messageBytes”)字节[]messageBytes){
返回“工作”;
}
我尝试过通过java直接通过rest模板发送它,效果很好。但我希望结构保持一致,并通过SpringIntegrationXML完成。
我使用的是spring boot 2.0.2 BOM。我认为问题在于,在第一次请求之后,
预期响应类型=“[B”
您将获得一个contetType
头作为应用程序/八位字节流
,这不适合第二个请求,其中您有一个多值映射
,但没有任何钩子来表示它
我建议您在发送第二个请求之前添加标题enricher
:
<int:service-activator
input-channel="sourceDocumentOutLv1"
ref="docConversionOrchestratorImpl" method="processRest1AndSendToRest2"
output-channel="enrichContentTypeHeaderChannel" />
<int:header-enricher input-channel="enrichContentTypeHeaderChannel" output-channel="sourceDocumentOutLv2">
<int:header name="contentType" value="multipart/form-data" overwrite="true"/>
</int:header-enricher>
我已按建议添加了enricher,收到一个新错误-org.springframework.messaging.MessageHandlingException:URI的HTTP请求执行失败[;嵌套异常为org.springframework.web.client.ResourceAccessException:的POST请求时发生I/O错误“”:软件导致的连接中止:recv失败;嵌套异常为java.net.SocketException:软件导致的连接中止:recv失败这已经不同了:。不确定“为什么?”由于第一个请求似乎适合您…您提供的解决方案工作正常。第二个问题是由于我在第二个请求中发送的文件太大而导致的。修改了多部分请求以发送小文件,并且与您提供的enricher解决方案一起工作得非常好。感谢您的帮助很酷!你的问题和最终解决方案得到了我的+1!