关键词:
【中文标题】如何使用多部分/表单和分块编码在 spring mvc 中接收文件上传?【英文标题】:How do I receive a file upload in spring mvc using both multipart/form and chunked encoding? 【发布时间】:2013-12-08 08:57:05 【问题描述】:我正在尝试编写一个 spring mvc 方法,该方法可以接收多部分/表单或传输编码分块文件上传。我可以编写一个单独的方法来处理每种类型,但我想用相同的方法来做,所以我可以使用相同的 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 请求参数,它非常适合传输编码分块。如果我把它留在里面,它非常适合 MultipartFile 上传。如何使用相同的方法来处理两种上传类型?
这适用于分块:
@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);
应该是可以的,有人知道怎么做吗?
谢谢, 史蒂夫
【问题讨论】:
你想要一个端点,并且不介意有两个控制器方法吗?或者你想要单个端点和单个控制器方法? 如果有办法让 2 个控制器方法使用相同的 URI,并且 spring 可以根据是否存在多部分内容来选择调用哪个方法。 【参考方案1】:摘自我的代码(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 上进行的测试最少。当然可能存在问题,并且可能有一种更简单的提取内容范围的方法,但是 .. 对我有用。
【讨论】:
很棒的解决方案!一旦我完成、签入并清理到足以在此处发布的解决方案,我也会发布我的解决方案。不过你的解决方案更好。 我无法使用第一种方法让 blueimp(使用 AngularJS)上传分块。它总是调用uploadMultipart(通过发送多部分标头)。请问有什么特别的 blueimp 配置可以分享吗? 据我记忆,没什么特别的。你使用的是什么浏览器?将哪些标头发送到服务器端?【参考方案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
【讨论】:
我建议不要使用multiFile.getBytes()
,因为它将整个字节数组加载到内存中如何在 GlassFish 3.1.1 上运行的应用程序中使用多部分/表单数据编码
】如何在GlassFish3.1.1上运行的应用程序中使用多部分/表单数据编码【英文标题】:Howtousemultipart/form-dataencodinginapplicationrunningonGlassFish3.1.1【发布时间】:2012-02-2221:09:04【问题描述】:我有一个在GlassFish3.1.1下运行的JSF2.0应用程序... 查看详情
如何使用 Spring MockMvc 放置多部分/表单数据?
】如何使用SpringMockMvc放置多部分/表单数据?【英文标题】:HowtoPUTmultipart/form-datausingSpringMockMvc?【发布时间】:2016-11-2900:42:39【问题描述】:我有一个带有PUT方法的控制器方法,它接收multipart/form-data:@RequestMapping(value="/putIn",meth... 查看详情
如何发布具有多部分/表单数据编码的数组?
】如何发布具有多部分/表单数据编码的数组?【英文标题】:HowdoIPOSTanarraywithmultipart/form-dataencoding?【发布时间】:2012-04-1716:06:35【问题描述】:在GET参数字符串或“x-www-form-urlencoded”POST请求中,可以通过用括号命名参数来指定... 查看详情
多部分和分块协议之间的区别
...解释一下两者的区别吗?分块是流协议而多部分不是吗?使用multipart有什么好处?【问题讨论】:只是一个猜测,但我希望multipart包含多个单独的部分,用于多个不同的内容等-而chunked为同一实体提供多个块。在等待更有知识的... 查看详情
在 iphone 中使用多部分表单数据发布图像和其他数据
...ata向服务器发送一些数据和图像。请给我一些PHP代码,我如何将图像保存在服务器上,我能够在服务器上获取与图像一起传递的其他变量。请查看我的objC代码和p 查看详情
Retrofit - @Body 参数不能与表单或多部分编码一起使用
】Retrofit-@Body参数不能与表单或多部分编码一起使用【英文标题】:Retrofit-@Bodyparameterscannotbeusedwithformormulti-partencoding【发布时间】:2015-02-0316:39:57【问题描述】:我正在尝试发出要包含Header、form-urlencoded字段和json正文的请求。... 查看详情
发布多部分表单数据问题
...aIssue【发布时间】:2019-11-1914:55:10【问题描述】:我正在使用HttpWebRequest发布到MMSAPI。帖子的正文包含有关交付的XML数据和作为MIME多部分附件的MMS消息,需要进行Base64编码。发帖成功,但我只收到文字,没有图片。在查看我的代... 查看详情
如何使用 URLSessionStreamTask 和 URLSession 进行分块编码传输
】如何使用URLSessionStreamTask和URLSession进行分块编码传输【英文标题】:HowtouseURLSessionStreamTaskwithURLSessionforchunked-encodingtransfer【发布时间】:2017-11-1923:53:07【问题描述】:我正在尝试连接到Twitter流API端点。看起来URLSession支持通过U... 查看详情
禁用传输编码:在 Spring Webflux 响应中分块
...luxresponses【发布时间】:2018-07-1211:55:36【问题描述】:我使用SpringWebflux响应式库创建了一堆RESTAPI端点。我现在面临的问题是SpringWebflux返回的响应具有transfer-encoding:chunkedHTTP标头。由于 查看详情
如何在邮递员的同一请求中发送多部分/表单数据和嵌套 json?
】如何在邮递员的同一请求中发送多部分/表单数据和嵌套json?【英文标题】:Howtosendmultipart/form-dataandnestedjsoninthesamerequestinpostman?【发布时间】:2021-10-2214:13:51【问题描述】:我有一个RESTapi,它获取嵌套json的数据,包括多部分... 查看详情
如何在 Spring App 中接收多部分请求
】如何在SpringApp中接收多部分请求【英文标题】:HowtoreceivemultipartrequestinSpringApp【发布时间】:2022-01-0400:27:34【问题描述】:我已经看到了很多来源,也看到了一些关于SO的问题,但没有找到解决方案。我想向我的Spring应用发送... 查看详情
如何在不模拟多部分表单的情况下发布图像[重复]
】如何在不模拟多部分表单的情况下发布图像[重复]【英文标题】:Howtopostimagewithoutsimulatemultipartform[duplicate]【发布时间】:2013-04-1711:26:03【问题描述】:我正在与一个php开发人员一起工作,他希望我向他发布一张图片。但我什... 查看详情
如何在 SMTP 的多部分 MIME 消息中使用 8 位编码?
】如何在SMTP的多部分MIME消息中使用8位编码?【英文标题】:Howtouse8bitencodinginmultipartMIMEmessagesinSMTP?【发布时间】:2015-01-0609:42:57【问题描述】:我有一个关于如何在SMTP的多部分MIME中使用8位编码的问题。根据MIMEWiki,我们可以... 查看详情
如何从反应提交多部分/表单数据到表达?
】如何从反应提交多部分/表单数据到表达?【英文标题】:Howtosubmitmultipart/form-datafromreacttoexpress?【发布时间】:2020-04-0620:16:20【问题描述】:我正在尝试提交带有Image和Name类别的表单。但是在我的ExpressJS(后端)中,我无法获... 查看详情
如何在 NestJS 中为采用多部分表单数据的 OpenAPI 注释端点
】如何在NestJS中为采用多部分表单数据的OpenAPI注释端点【英文标题】:HowdoIannotateanendpointinNestJSforOpenAPIthattakesMultipartFormData【发布时间】:2021-03-1222:03:26【问题描述】:我的NestJS服务器有一个接受文件和其他表单数据的端点例如... 查看详情
如何在烧瓶中读取多部分/表单数据[重复]
】如何在烧瓶中读取多部分/表单数据[重复]【英文标题】:howtoreadmultipart/form-datainflask[duplicate]【发布时间】:2017-03-1719:21:30【问题描述】:我在读取通过XMLHttpRequest发布的烧瓶中的数据时遇到问题。我正在使用这个jquery插件来裁... 查看详情
Spring Batch - 分块和多线程步骤 - RowMapper 中的 Nullpointer 异常
】SpringBatch-分块和多线程步骤-RowMapper中的Nullpointer异常【英文标题】:SpringBatch-Chunking&Multithreadedsteps-NullpointerexceptioninRowMapper【发布时间】:2020-01-2507:36:45【问题描述】:当我在多个线程中运行我的步骤时,我在处理结果集时... 查看详情
如何在 Jetty HttpClient 中进行多部分/表单数据发布
】如何在JettyHttpClient中进行多部分/表单数据发布【英文标题】:Howtodomultipart/form-datapostinJettyHttpClient【发布时间】:2011-08-3110:13:44【问题描述】:我想知道是否有人可以帮助我。对于Java项目,我想使用JettyHttpClient将数据发送到Re... 查看详情