我正在尝试编写一个spring mvc方法,它可以接收multipart / form或transfer-encoding chunked文件上传。我可以编写一个单独的方法来处理每种类型,但我想用相同的方法来做,所以我可以使用相同的REST POST uri,如:
http://host:8084/attachments/testupload
到目前为止,这是我最好的尝试:
@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获得一个异常说明:
org.springframework.web.multipart.MultipartException: \
The current request is not a multipart request
如果我删除了MultipartFile请求参数,它对于chunked传输编码非常有用。如果我保留它,它适用于MultipartFile上传。如何使用相同的方法来处理这两种上传类型?
这适用于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);
}
这适用于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);
}
应该有可能,有人知道怎么做吗?
谢谢你, 史蒂夫
答案 0 :(得分:26)
摘自我的代码(Spring 3.2,使用AngularJS上传blueimp文件):
/**
* 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上进行的最小测试。当然可能存在问题,并且可能有一种更简单的方法来提取内容范围,但是..对我有用。
答案 1 :(得分:2)
这是
的控制器package com.faisalbhagat.web.controller;
@Controller
@RequestMapping(value = { "" })
public class UploadController {
@RequestMapping(value = "/uploadMyFile", method = RequestMethod.POST)
@ResponseBody
public String handleFileUpload(MultipartHttpServletRequest request)
throws Exception {
Iterator<String> itrator = request.getFileNames();
MultipartFile multiFile = request.getFile(itrator.next());
try {
// just to show that we have actually received the file
System.out.println("File Length:" + multiFile.getBytes().length);
System.out.println("File Type:" + multiFile.getContentType());
String fileName=multiFile.getOriginalFilename();
System.out.println("File Name:" +fileName);
String path=request.getServletContext().getRealPath("/");
//making directories for our required path.
byte[] bytes = multiFile.getBytes();
File directory= new File(path+ "/uploads");
directory.mkdirs();
// saving the file
File file=new File(directory.getAbsolutePath()+System.getProperty("file.separator")+picture.getName());
BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(file));
stream.write(bytes);
stream.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new Exception("Error while loading the file");
}
return toJson("File Uploaded successfully.")
}
public String toJson(Object data)
{
ObjectMapper mapper=new ObjectMapper();
StringBuilder builder=new StringBuilder();
try {
builder.append(mapper.writeValueAsString(data));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return builder.toString();
}
}
您可以使用客户端代码找到完整的解决方案 http://faisalbhagat.blogspot.com/2014/09/springmvc-fileupload-with-ajax-and.html