【问题标题】:Send data to an external resource: why content is null?向外部资源发送数据:为什么内容为空?
【发布时间】:2018-07-17 11:52:46
【问题描述】:

我有一个简单的骆驼路线。我想从队列中提取一个文件并使用 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));
            }
        });
    }
}

问题是请求的payload丢失了:

// 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 请求的负载?

我注意到通过这种方式设置的任何数据也会丢失。只有标头被发送到远程资源。

通过使用&lt;input type="file"&gt; 编码为multipart/form-data 的简单HTML 表单,我可以成功地将所有数据发送到外部资源。

可能是什么原因?


已更新。

以下代码也给出了空内容:

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]]

【问题讨论】:

  • 你见过my answer about sending multipart/form-data吗?对于您的情况,MultipartEntityBuilder#addBinaryBody("file", exchange.getIn().getBody(byte[].class))MultipartEntityBuilder#addPart("file", new ByteArrayBody(exchange.getIn().getBody(byte[].class), exchange.getIn().getHeader("fileName", String.class))) 应该可以工作。
  • 解决No body available of type...切换http组件到http4。如果要保留http组件,则需要将生成的content-type设置为描述的here

标签: apache-camel activemq alfresco jbossfuse camel-http


【解决方案1】:

我编写了一个小型 servlet 应用程序,并从 HttpServletRequest 对象中获取 doPost(...) 方法中的内容。

问题在于外部系统 (Alfresco) 端的 WebScriptRequest 对象。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 2023-01-02
    • 1970-01-01
    相关资源
    最近更新 更多