Camel Rest DSL 检索 HTTP POST 多部分文件
Posted
技术标签:
【中文标题】Camel Rest DSL 检索 HTTP POST 多部分文件【英文标题】:Camel Rest DSL retrieve HTTP POST multipart File 【发布时间】:2019-06-08 10:48:45 【问题描述】:我的路由器类如下所示,我正在尝试上传视频文件并将其存储到文件位置。
SpringBootRouter.java
package com.camelrest;
import java.util.HashMap;
import java.util.Map;
import org.apache.camel.component.restlet.RestletComponent;
import org.apache.camel.spring.boot.FatJarRouter;
import org.restlet.Component;
import org.restlet.ext.spring.SpringServerServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class MySpringBootRouter extends FatJarRouter
@Autowired
private MultipartProcessor multipartProcessor;
@Override
public void configure()
restConfiguration().component("restlet");
rest("/upload").post().to("direct:upload");
from("direct:upload")
.to("file://E:/RestTest");
@Bean
public ServletRegistrationBean servletRegistrationBean()
SpringServerServlet serverServlet = new SpringServerServlet();
ServletRegistrationBean regBean = new ServletRegistrationBean(
serverServlet, "/rest/*");
Map<String, String> params = new HashMap<String, String>();
params.put("org.restlet.component", "restletComponent");
regBean.setInitParameters(params);
return regBean;
@Bean
public Component restletComponent()
return new Component();
@Bean
public RestletComponent restletComponentService()
return new RestletComponent(restletComponent());
我正在尝试使用邮递员上传视频文件,如下图所示:
我上传的文件内容保存在一个文件名中,该文件名带有一些由骆驼生成的随机骆驼 ID
但是我想要在正文中传递的文件名
SampleVideo_1280x720_10mb.mp4
作为文件名并从正文中删除以下内容
----------------------------948281627232093197119960
Content-Disposition: form-data; name="file"; filename="SampleVideo_1280x720_10mb.mp4"
Content-Type: video/mp4
所以最终输出可以是使用邮递员上传时使用的文件名上传的视频
【问题讨论】:
您需要创建一个 bean 或处理器来提取名称。尝试查看 commons fileupload commons.apache.org/proper/commons-fileupload/streaming.html. 【参考方案1】:您可以使用MimeMultipartDataFormat
来解组多部分请求。使用它,将准备附件到Exchange
。
之后,您需要以某种方式将 Attachment
转换为 InputStream
并填充 CamelFileName
标头。有了这个任务可以帮你小Processor
。
路线:
from("direct:upload")
.unmarshal().mimeMultipart().split().attachments()
.process(new PrepareFileFromAttachment())
.to("file://C:/RestTest");
处理器:
class PrepareFileFromAttachment implements Processor
@Override
public void process(Exchange exchange) throws Exception
DataHandler dataHandler = exchange.getIn().getBody(Attachment.class).getDataHandler();
exchange.getIn().setHeader(Exchange.FILE_NAME, dataHandler.getName());
exchange.getIn().setBody(dataHandler.getInputStream());
如果您的表单仅包含单个输入,则上述方法不起作用。这是因为MimeMultipartDataFormat
将第一个表单输入编组到正文(不存储文件名)和其他输入到存储文件名的附件。
在这种情况下,您需要创建Processor
,直接读取InputStream
:
路线:
from("direct:upload")
.process(new ProcessMultipartRequest())
.to("file:c://RestTest");
处理器
public class ProcessMultipartRequest implements Processor
@Override
public void process(Exchange exchange) throws Exception
InputStream is = exchange.getIn().getBody(InputStream.class);
MimeBodyPart mimeMessage = new MimeBodyPart(is);
DataHandler dh = mimeMessage.getDataHandler();
exchange.getIn().setBody(dh.getInputStream());
exchange.getIn().setHeader(Exchange.FILE_NAME, dh.getName());
【讨论】:
感谢您的洞察力。当我将调试器放在这一行时,.attachments() 返回 null: DataHandler dataHandler = exchange.getIn().getBody(Attachment.class).getDataHandler();返回空值。您能否建议一些其他方法来获取 FileName 现在主体设置视频并且能够在邮递员中看到视频但无法获取上传视频的文件名。请建议我四处走走。 我明白了。仅当您的帖子在邮递员中包含任何其他形式的密钥时,此方法才有效。当表单帖子仅包含文件密钥时,它直接编组到正文,而不是附件。我正在调试MimeMultipartDataFormat
中发生的事情。
经过调试我看到,请求的第一部分总是存储在body
中,在这种情况下,文件名丢失了。它仅存储到附件中的其他密钥。我已经编辑了答案,其中包含单键表单的解释和替代实现。
很棒的答案我为此苦苦挣扎了一段时间,非常感谢。如果我们需要处理多个键(例如上传文件并在正文中传递其他值),您能否对多部分数据进行一些说明。这也确实有帮助....以上是关于Camel Rest DSL 检索 HTTP POST 多部分文件的主要内容,如果未能解决你的问题,请参考以下文章
Camel Rest XML DSL分离文件夹结果Unmarshall Exception
如何在apache camel DSL中获得正确的https服务器响应?
Apache Camel - 调用 http 或 rest 调用(通过 Shiro Security 过滤)
Apache Camel - 调用 http 或 rest 调用(通过 Shiro Security 过滤)