如何使用多部分/表单和分块编码在 spring mvc 中接收文件上传? [英] How do I receive a file upload in spring mvc using both multipart/form and chunked encoding?

查看:22
本文介绍了如何使用多部分/表单和分块编码在 spring mvc 中接收文件上传?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个 spring mvc 方法,该方法可以接收多部分/表单或传输编码分块文件上传.我可以编写一个单独的方法来处理每种类型,但我想用相同的方法来做,这样我就可以使用相同的 REST POST uri,例如:

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);
}

使用上述方法我可以上传一个多部分文件,但如果我上传一个分块文件,我会收到一个来自 spring 的异常,内容为:

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

如果我删除 MultipartFile 请求参数,它非常适合传输编码分块.如果我把它留在里面,它非常适合 MultipartFile 上传.如何使用相同的方法来处理两种上传类型?

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?

这适用于分块:

@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);
}

这对 MultipartFile 很有用:

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?

谢谢,史蒂夫

推荐答案

摘自我的代码(Spring 3.2,使用 AngularJS 上传 blueimp 文件):

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);
}

这应该会让你开始.在 IE8、IE9、IE10、Chrome、FF 上进行了最少的测试.当然可能存在问题,并且可能有一种更简单的方法来提取内容范围,但是 .. 对我有用.

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.

这篇关于如何使用多部分/表单和分块编码在 spring mvc 中接收文件上传?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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