如何使用multipart / form和chunked编码在spring mvc中接收文件上传? [英] How do I receive a file upload in spring mvc using both multipart/form and chunked encoding?
问题描述
http:// host:8084 / attachments / testupload
到目前为止我的最佳尝试:
@RequestMapping(value = {/ testupload},method = RequestMethod.POST,产生=
application / json)
public @ResponseBody
ResponseEntity< MessageResponseModel> testUpload(
@RequestParam(value =filedata,required = false)MultipartFile filedata,
final HttpServletRequest request)throws IOException {
InputStream is = null;
if(filedata == null){
is = request.getInputStream();
}
else {
is = filedata.getInputStream();
}
byte [] bytes = IOUtils.toByteArray(is);
System.out.println(read+ bytes.length +bytes。);
返回新的ResponseEntity< MessageResponseModel>(null,null,HttpStatus.OK);
$ b 使用上面的方法我可以上传一个多部分文件,但是如果我上传一个分块的文件我从Spring中得到一个异常:
org.springframework.web.multipart.MultipartException:\
当前请求不是多部分请求
如果我删除了MultipartFile请求参数,编码分块。如果我把它放在里面,对于MultipartFile上传非常有用。我怎样才能用相同的方法来处理这两种上传类型?
这适用于分块:
@RequestMapping(value = {/ testupload},method = RequestMethod.POST,产生=
application / json)
public @ResponseBody
ResponseEntity< MessageResponseModel> testUpload(
final HttpServletRequest request)throws IOException {
InputStream is = null;
is = request.getInputStream();
byte [] bytes = IOUtils.toByteArray(is);
System.out.println(read+ bytes.length +bytes。);
返回新的ResponseEntity< MessageResponseModel>(null,null,HttpStatus.OK);
$ / code $ / pre
这对于MultipartFile很有用:
@RequestMapping(value = {/ testupload},method = RequestMethod.POST,产生=
application / json)
public @ResponseBody
ResponseEntity< MessageResponseModel> testUpload(
@RequestParam MultipartFile filedata)抛出IOException {
InputStream is = null;
is = filedata.getInputStream();
byte [] bytes = IOUtils.toByteArray(is);
System.out.println(read+ bytes.length +bytes。);
返回新的ResponseEntity< MessageResponseModel>(null,null,HttpStatus.OK);
$ b $ p
$ b 应该有可能,有人知道如何做到这一点?
谢谢,
史蒂夫
解决方案我的代码(Spring 3.2,带有AngularJS的blueimp文件上传):
$ b $ $ p $ $ $ $ $
处理分块文件上传,当文件超出定义的分块大小时。
*
*此方法也被现代浏览器和IE> = 10
* /
@RequestMapping(value =/ content-files / upload /,方法= RequestMethod.POST,headers =content-type!= multipart / form-data)
@ResponseBody
Public UploadedFile uploadChunked(
final HttpServletRequest请求,$ b $ final HttpServletResponse响应) {
request.getHeader(content-range); // Content-Range:bytes 737280-819199 / 845769
request.getHeader(content-length); // 845769
request.getHeader(content-disposition); // Content-Disposition:附件; filename =截图%20from%202012-12-19%2017:28:01.png
request.getInputStream(); //实际内容
//正则表达式的内容范围:Pattern.compile(bytes([0-9] +) - ([0-9] +)/([0-9] +));
//正则表示文件名:Pattern.compile((?< = filename = \)。*?(?= \));
//返回任何你想要的json
return new UploadedFile();
}
/ **
*默认的多部分文件上传。只有那些不支持
*支持分块上传的应用程序才能调用此方法。
*
*如果浏览器支持分块上传,而文件小于块,则会调用
* uploadChunked()方法。
*
*这是对于IE <= 9
* /
@RequestMapping(value =/ content-files / upload /,method = RequestMethod .POST,headers =content-type = multipart / form-data)
@ResponseBody
public HttpEntity< UploadedFile> uploadMultipart(
final HttpServletRequest请求,$ b $ final HttpServletResponse响应,
@RequestParam(file)final MultipartFile multiPart){
//处理常规MultipartFile
// IE <= 9提供保存文件,如果以json的形式返回,那么设置内容类型为plain。
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
返回新的HttpEntity<>(new UploadedFile(),headers);
}
这应该让你开始。在IE8,IE9,IE10,Chrome,FF上完成最小的测试。当然可能有问题,并且可能有一个更简单的方法来提取内容范围,但是..为我工作。
I am trying to write a spring mvc method that can receive either a multipart/form or transfer-encoding chunked file upload. I can write a separate method to handle each type but I'd like to do it with the same method so i can use the same REST POST uri such as:
http://host:8084/attachments/testupload
Here is my best attempt so far:
@RequestMapping(value = { "/testupload" }, method = RequestMethod.POST, produces =
"application/json")
public @ResponseBody
ResponseEntity<MessageResponseModel> testUpload(
@RequestParam(value = "filedata", required = false) MultipartFile filedata,
final HttpServletRequest request) throws IOException {
InputStream is = null;
if (filedata == null) {
is = request.getInputStream();
}
else {
is = filedata.getInputStream();
}
byte[] bytes = IOUtils.toByteArray(is);
System.out.println("read " + bytes.length + " bytes.");
return new ResponseEntity<MessageResponseModel>(null, null, HttpStatus.OK);
}
Using the above method I can upload a multipart file, but if i upload a chunked file I get an exception from spring that says:
org.springframework.web.multipart.MultipartException: \
The current request is not a multipart request
If I remove the MultipartFile request param it works great for transfer encoding chunked. If I leave it in it works great for MultipartFile uploads. How can I do it with the same method to handle both upload types?
This works fine for chunked:
@RequestMapping(value = { "/testupload" }, method = RequestMethod.POST, produces =
"application/json")
public @ResponseBody
ResponseEntity<MessageResponseModel> testUpload(
final HttpServletRequest request) throws IOException {
InputStream is = null;
is = request.getInputStream();
byte[] bytes = IOUtils.toByteArray(is);
System.out.println("read " + bytes.length + " bytes.");
return new ResponseEntity<MessageResponseModel>(null, null, HttpStatus.OK);
}
and this works great for MultipartFile:
@RequestMapping(value = { "/testupload" }, method = RequestMethod.POST, produces =
"application/json")
public @ResponseBody
ResponseEntity<MessageResponseModel> testUpload(
@RequestParam MultipartFile filedata) throws IOException {
InputStream is = null;
is = filedata.getInputStream();
byte[] bytes = IOUtils.toByteArray(is);
System.out.println("read " + bytes.length + " bytes.");
return new ResponseEntity<MessageResponseModel>(null, null, HttpStatus.OK);
}
It should be possible, does anybody know how to do this?
Thank you,
Steve
解决方案 Excerpt from my code (Spring 3.2, blueimp file upload with AngularJS):
/**
* Handles chunked file upload, when file exceeds defined chunked size.
*
* This method is also called by modern browsers and IE >= 10
*/
@RequestMapping(value = "/content-files/upload/", method = RequestMethod.POST, headers = "content-type!=multipart/form-data")
@ResponseBody
public UploadedFile uploadChunked(
final HttpServletRequest request,
final HttpServletResponse response) {
request.getHeader("content-range");//Content-Range:bytes 737280-819199/845769
request.getHeader("content-length"); //845769
request.getHeader("content-disposition"); // Content-Disposition:attachment; filename="Screenshot%20from%202012-12-19%2017:28:01.png"
request.getInputStream(); //actual content.
//Regex for content range: Pattern.compile("bytes ([0-9]+)-([0-9]+)/([0-9]+)");
//Regex for filename: Pattern.compile("(?<=filename=\").*?(?=\")");
//return whatever you want to json
return new UploadedFile();
}
/**
* Default Multipart file upload. This method should be invoked only by those that do not
* support chunked upload.
*
* If browser supports chunked upload, and file is smaller than chunk, it will invoke
* uploadChunked() method instead.
*
* This is instead a fallback method for IE <=9
*/
@RequestMapping(value = "/content-files/upload/", method = RequestMethod.POST, headers = "content-type=multipart/form-data")
@ResponseBody
public HttpEntity<UploadedFile> uploadMultipart(
final HttpServletRequest request,
final HttpServletResponse response,
@RequestParam("file") final MultipartFile multiPart) {
//handle regular MultipartFile
// IE <=9 offers to save file, if it is returned as json, so set content type to plain.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
return new HttpEntity<>(new UploadedFile(), headers);
}
This should get you started. Minimal testing done on IE8, IE9, IE10, Chrome, FF. Of course there might be issues, and probably there is an easier way of extracting content ranges, but .. works for me.
这篇关于如何使用multipart / form和chunked编码在spring mvc中接收文件上传?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!