apache-camel - 向外部资源发送数据:为什么内容为空?
问题描述
我有一个简单的骆驼路线。我想从队列中提取一个文件并使用 POST 请求将其传递给外部资源。此路由有效,请求到达外部资源:
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
public class MyRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
from("activemq:alfresco-queue")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
byte[] bytes = exchange.getIn().getBody(byte[].class);
// All of that not working...
// exchange.getIn().setHeader("content", bytes); gives "java.lang.IllegalAgrumentException: Request header is too large"
// exchange.getIn().setBody(bytes, byte[].class); gives "size of content is -1"
// exchange.getIn().setBody(bytes); gives "size of content is -1"
// ???
// ??? But I can print file content here
for(int i=0; i < bytes.length; i++) {
System.out.print((char) bytes[i]);
}
}
})
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.setHeader(Exchange.CONTENT_TYPE, constant("multipart/form-data"))
.to("http://vm-alfce52-31......com:8080/alfresco/s/someco/queuefileuploader?guest=true")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("The response code is: " + exchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE));
}
});
}
}
问题是请求的有效负载丢失了:
// somewhere on an external resource
Content content = request.getContent();
long len = content.getSize() // is always == -1.
// the file name is passed successfully
String fileName = request.getHeader("fileName");
如何在此路由/处理器中设置和传递 POST 请求的有效负载?
我注意到通过这种方式设置的任何数据也会丢失。只有标头被发送到远程资源。
通过使用带有<input type="file">
编码的简单 HTML 表单,multipart/form-data
我可以成功地将所有数据发送到外部资源。
可能是什么原因?
更新。
以下代码还给出了空内容:
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
// this also gives null-content
//multipartEntityBuilder.addBinaryBody("file", exchange.getIn().getBody(byte[].class));
multipartEntityBuilder.addPart("file", new ByteArrayBody(exchange.getIn().getBody(byte[].class), exchange.getIn().getHeader("fileName", String.class)));
exchange.getOut().setBody(multipartEntityBuilder.build().getContent());
/********** This also gives null-content *********/
StringBody username = new StringBody("username", ContentType.MULTIPART_FORM_DATA);
StringBody password = new StringBody("password", ContentType.MULTIPART_FORM_DATA);
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntityBuilder.addPart("username", username);
multipartEntityBuilder.addPart("password", password);
String filename = (String) exchange.getIn().getHeader("fileName");
File file = new File(filename);
try(RandomAccessFile accessFile = new RandomAccessFile(file, "rw")) {
accessFile.write(bytes);
}
multipartEntityBuilder.addPart("upload", new FileBody(file, ContentType.MULTIPART_FORM_DATA, filename));
exchange.getIn().setBody(multipartEntityBuilder.build().getContent());
还有一个细节。如果我改变这个:
exchange.getOut().setBody(multipartEntityBuilder.build().getContent());
对此:
exchange.getOut().setBody(multipartEntityBuilder.build());
我在 FUSE 端收到以下异常(我通过 hawtio 管理控制台看到它):
Execution of JMS message listener failed.
Caused by: [org.apache.camel.RuntimeCamelException - org.apache.camel.InvalidPayloadException:
No body available of type: java.io.InputStream but has value: org.apache.http.entity.mime.MultipartFormEntity@26ee73 of type:
org.apache.http.entity.mime.MultipartFormEntity on: JmsMessage@0x1cb83b9.
Caused by: No type converter available to convert from type: org.apache.http.entity.mime.MultipartFormEntity to the required type:
java.io.InputStream with value org.apache.http.entity.mime.MultipartFormEntity@26ee73. Exchange[ID-63-DP-TAV-55652-1531889677177-5-1]. Caused by:
[org.apache.camel.NoTypeConversionAvailableException - No type converter available to convert from type:
org.apache.http.entity.mime.MultipartFormEntity to the required type: java.io.InputStream with value org.apache.http.entity.mime.MultipartFormEntity@26ee73]]
解决方案
我编写了一个小型 servlet 应用程序并doPost(...)
从HttpServletRequest
对象中获取方法中的内容。
问题出WebScriptRequest
在外部系统(Alfresco)端的对象上。
@Bedla,感谢您的建议!
在 Alfresco 方面,问题可以解决如下:
public class QueueFileUploader extends DeclarativeWebScript {
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status) {
HttpServletRequest httpServletRequest = WebScriptServletRuntime.getHttpServletRequest(req);
// calling methods of httpServletRequest object and retrieving the content
...
路线:
public class MyRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
from("activemq:alfresco-queue")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntityBuilder.addPart("file", new ByteArrayBody(exchange.getIn().getBody(byte[].class),
exchange.getIn().getHeader("fileName", String.class)));
exchange.getIn().setBody(multipartEntityBuilder.build().getContent());
}
})
.setHeader(Exchange.HTTP_METHOD, constant(org.apache.camel.component.http4.HttpMethods.POST))
.to("http4://localhost:8080/alfresco/s/someco/queuefileuploader?guest=true")
// .to("http4://localhost:8080/ServletApp/hello")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("The response code is: " +
exchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE));
}
});
}
}
推荐阅读
- azure - 如何使用 PowerShell 将块添加到现有 Azure 存储 BLOB?
- html - 如何将自定义波浪形分隔线添加到部分
- sql - 查询中的几个左连接
- javascript - 单击事件不适用于附加项目
- swift - 完成前排队的任务和可能的卸载
- python - python 3 - ModuleNotFoundError:没有名为“编码”的模块
- machine-learning - kaggle 糖尿病视网膜病变检测第二名解决方案神经网络中的“大小”是什么意思?
- kendo-ui - 延迟后刷新剑道弹出控件
- javascript - 用于隐藏/显示菜单的外部 JavaScript 不起作用
- android - Google Drive API 缓存查询结果