Apache Camel - 分段文件上传 [英] Apache Camel - Multipart File upload

查看:26
本文介绍了Apache Camel - 分段文件上传的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Apache-Camel ESB,尝试将 xlsx 文件上传到 Spring Rest Web 应用程序.从 apache-camel ESB 上传失败.但是从 Postman 上传工作正常.下面分享了代码片段.

Using Apache-Camel ESB, trying to upload a xlsx file to Spring Rest Web application. Upload fails from apache-camel ESB. But upload works fine from Postman. Shared code snippets below.

  1. Camel 路由器中的处理器代码如下

  1. Processor Code in Router of Camel looks like

    from("file://data/PASInput").process(new Processor() {
    @Override
    public void process(Exchange exchange) throws Exception {

        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        String filename = (String) exchange.getIn().getHeader(Exchange.FILE_NAME);
        File file = exchange.getIn().getBody(File.class);
        multipartEntityBuilder.addPart("file",
            new FileBody(file, ContentType.MULTIPART_FORM_DATA, filename));
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        multipartEntityBuilder.build().writeTo(out);
        InputStream  inputStream = new ByteArrayInputStream(out.toByteArray());
        exchange.getOut().setBody(inputStream);         
    }
}).to("http://localhost:8080/Pastel/api/convertor/pas/pastel")
        .log(LoggingLevel.ERROR, "RESPONSE BODY ${body}").end();

  • Pom.xml

  • Pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-spring-boot-starter</artifactId>
            <version>2.21.0.fuse-000077-redhat-1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-cxf</artifactId>
            <version>2.21.0.fuse-000077-redhat-1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-http</artifactId>
            <version>2.21.0.fuse-000077-redhat-1</version>
        </dependency>       
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-http4</artifactId>
            <version>2.17.2</version>
        </dependency>
    

  • 错误

  • Error

        org.apache.camel.http.common.HttpOperationFailedException: HTTP operation failed invoking http://localhost:8080/Pastel/api/convertor/pas/pastel with statusCode: 500
        at org.apache.camel.component.http.HttpProducer.populateHttpOperationFailedException(HttpProducer.java:274)
       at org.apache.camel.component.http.HttpProducer.process(HttpProducer.java:183)
       at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
       at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148)
       at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
       at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
       at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
       at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
       at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
       at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:452)
       at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:219)
       at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:183)
       at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174)
       at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    

  • 当我们使用 postman 访问网络服务时,没有错误.能够成功上传服务器.Spring mvc 代码,

  • When we hit the webservice using postman, there are no errors. Able to upload the servers successfully. Spring mvc code,

                @RequestMapping(value = "/pas/pastel", method = RequestMethod.POST)
                @ResponseBody
                public void convertPASToPastel(HttpServletRequest request, HttpServletResponse response,
                @RequestParam(value = "file") final MultipartFile pasFile) {
                   try {
                      System.out.print("Here");
                   }
                }
    

  • 推荐答案

    您可能会在 Spring 后端日志中看到此错误消息:

    You can probably see this error message in your Spring backend log:

    org.springframework.web.multipart.MultipartException:当前请求不是多部分请求.

    org.springframework.web.multipart.MultipartException: Current request is not a multipart request.

    您需要设置正确的 ContentType 标头.请参考这个类似问题的解决方案,如果你想以这种方式实现它.

    You need to set correct ContentType header. Please refer this similar question for solution, if you want to implement it in this way.

    但是如果你切换 co <​​code>camel-http4 组件(你已经在 pom.xml 中有这个组件),你可以摆脱这种混乱.此组件包含将 HttpEntity 转换为 InputStream 的逻辑.然后就可以直接设置HttpEntity来交换body.

    But you can get out this mess, if you switch co camel-http4 component (you already have this component in pom.xml). This component contains logic for converting HttpEntity to InputStream. Then you can set HttpEntity directly to exchange body.

    那么您的路线将如下所示:

    from("file://data/PASInput").process(new Processor() {
        @Override
        public void process(Exchange exchange) throws Exception {
            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
            multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            String filename = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class);
            File file = exchange.getIn().getBody(File.class);
            multipartEntityBuilder.addPart("file",
                    new FileBody(file, ContentType.MULTIPART_FORM_DATA, filename));
            exchange.getOut().setBody(multipartEntityBuilder.build());
        }
    }).to("http4://localhost:8080/Pastel/api/convertor/pas/pastel")
            .log(LoggingLevel.ERROR, "RESPONSE BODY ${body}").end();
    

    <小时>

    而且只是一个便条.切勿混合组件版本,始终使用与 Apache Camel 版本相同的组件.否则,您会看到可预测的结果.当方法为 void 时,为什么在 Spring 控制器中有注释 @ResponseBody?你不需要那个.


    And just a note. Never mix component versions, always use for components the same version as Apache Camel version. Otherwise you can see upredictable results. And why you have annotation @ResponseBody in Spring controller, when the method is void? You don`t need that.

    这篇关于Apache Camel - 分段文件上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆