问题
My Router class looks like below and i am trying to upload a video file and store it to a File location.
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());
}
}
I am trying to upload a video file using postman as per below screenshot :
My contents of the file that i upload are saved with a file name with some random camel ID generated by camel
However i want the filename that is passed in body
SampleVideo_1280x720_10mb.mp4
to be the name of the file and remove the following contents from the body
----------------------------948281627232093197119960
Content-Disposition: form-data; name="file"; filename="SampleVideo_1280x720_10mb.mp4"
Content-Type: video/mp4
So final output can be the video uploaded with the filename used during the upload with postman
回答1:
You can use MimeMultipartDataFormat to unmarshal Multipart request. Using this, will prepare attachments, to Exchange.
After that you need somehow convert Attachment to InputStream
and fill CamelFileName
header. With this task can help you small Processor
.
Route:
from("direct:upload")
.unmarshal().mimeMultipart().split().attachments()
.process(new PrepareFileFromAttachment())
.to("file://C:/RestTest");
Processor:
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());
}
}
The approach above does not work in case your form contains only single input in form. This is because MimeMultipartDataFormat marshals first form input into body (without storing file name) and other inputs to attachments where the file name is stored.
In this case you need to create Processor
reading InputStream
directly:
Route:
from("direct:upload")
.process(new ProcessMultipartRequest())
.to("file:c://RestTest");
Processor
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());
}
}
来源:https://stackoverflow.com/questions/54181670/camel-rest-dsl-retrieve-http-post-multipart-file