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

查看:39
本文介绍了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. 骆驼路由器中的处理器代码如下

  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 访问 web 服务时,没有错误.能够成功上传服务器.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 标头.请参考 this 类似问题的解决方案,如果你想以这种方式实现它.

    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天全站免登陆