Java 分段文件上传 Spring Boot
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25699727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multipart File upload Spring Boot
提问by Rob McFeely
Im using Spring Boot and want to use a Controller to receive a multipart file upload. When sending the file I keep getting the error 415 unsupported content typeresponse and the controller is never reached
我使用 Spring Boot 并希望使用控制器来接收分段文件上传。发送文件时,我不断收到错误 415 不支持的内容类型响应,并且从未到达控制器
There was an unexpected error (type=Unsupported Media Type, status=415).
Content type 'multipart/form-data;boundary=----WebKitFormBoundary1KvzQ1rt2V1BBbb8' not supported
Ive tried sending using form:action in html/jsp page and also in a standalone client application which uses RestTemplate. All attempts give the same result
我试过在 html/jsp 页面中使用 form:action 发送,也在使用 RestTemplate 的独立客户端应用程序中发送。所有尝试都给出相同的结果
multipart/form-data;boundary=XXXXX not supported.
multipart/form-data;boundary=XXXXX not supported.
It seems from multipart documentation that the boundary param has to be added to the multipart upload however this seems to not match the controller receiving "multipart/form-data"
从分段文档看来,必须将边界参数添加到分段上传中,但这似乎与控制器接收不匹配 "multipart/form-data"
My controller method is setup as follows
我的控制器方法设置如下
@RequestMapping(value = "/things", method = RequestMethod.POST, consumes = "multipart/form-data" ,
produces = { "application/json", "application/xml" })
public ResponseEntity<ThingRepresentation> submitThing(HttpServletRequest request,
@PathVariable("domain") String domainParam,
@RequestParam(value = "type") String thingTypeParam,
@RequestBody MultipartFile[] submissions) throws Exception
With Bean Setup
使用 Bean 设置
@Bean
public MultipartConfigElement multipartConfigElement() {
return new MultipartConfigElement("");
}
@Bean
public MultipartResolver multipartResolver() {
org.springframework.web.multipart.commons.CommonsMultipartResolver multipartResolver = new org.springframework.web.multipart.commons.CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(1000000);
return multipartResolver;
}
As you can see I've set the consumes type to "multipart/form-data" but when the multipart is sent it must have a boundary parameter and places a random boundary string.
如您所见,我已将消耗类型设置为“multipart/form-data”,但是当发送 multipart 时,它必须有一个边界参数并放置一个随机边界字符串。
Can anyone please tell me how I can either set the content type in controller to match or change my request to match my controller setup?
谁能告诉我如何在控制器中设置内容类型以匹配或更改我的请求以匹配我的控制器设置?
My attempts to send ... Attempt 1...
我尝试发送...尝试 1...
<html lang="en">
<body>
<br>
<h2>Upload New File to this Bucket</h2>
<form action="http://localhost:8280/appname/domains/abc/things?type=abcdef00-1111-4b38-8026-315b13dc8706" method="post" enctype="multipart/form-data">
<table width="60%" border="1" cellspacing="0">
<tr>
<td width="35%"><strong>File to upload</strong></td>
<td width="65%"><input type="file" name="file" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" name="submit" value="Add" /></td>
</tr>
</table>
</form>
</body>
</html>
Attempt 2....
尝试2....
RestTemplate template = new RestTemplate();
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
parts.add("file", new FileSystemResource(pathToFile));
try{
URI response = template.postForLocation(url, parts);
}catch(HttpClientErrorException e){
System.out.println(e.getResponseBodyAsString());
}
Attempt 3...
尝试3...
FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
formHttpMessageConverter.setCharset(Charset.forName("UTF8"));
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add( formHttpMessageConverter );
restTemplate.getMessageConverters().add(new MappingHymanson2HttpMessageConverter());
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
map.add("file", new FileSystemResource(path));
HttpHeaders imageHeaders = new HttpHeaders();
imageHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> imageEntity = new HttpEntity<MultiValueMap<String, Object>>(map, imageHeaders);
ResponseEntity e= restTemplate.exchange(uri, HttpMethod.POST, imageEntity, Boolean.class);
System.out.println(e.toString());
采纳答案by a better oliver
@RequestBody MultipartFile[] submissions
should be
应该
@RequestParam("file") MultipartFile[] submissions
The files are not the request body, they are part of it and there is no built-in HttpMessageConverter
that can convert the request to an array of MultiPartFile
.
这些文件不是请求正文,它们是它的一部分,并且没有内置HttpMessageConverter
可以将请求转换为MultiPartFile
.
You can also replace HttpServletRequest
with MultipartHttpServletRequest
, which gives you access to the headers of the individual parts.
您还可以替换HttpServletRequest
为MultipartHttpServletRequest
,这样您就可以访问各个部分的标题。
回答by Andrea
You can simply use a controllermethod like this:
您可以简单地使用这样的控制器方法:
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<?> uploadFile(
@RequestParam("file") MultipartFile file) {
try {
// Handle the received file here
// ...
}
catch (Exception e) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(HttpStatus.OK);
} // method uploadFile
Without any additional configurations for Spring Boot.
没有任何额外的 Spring Boot 配置。
Using the following html formclient side:
使用以下html 表单客户端:
<html>
<body>
<form action="/uploadFile" method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
</body>
</html>
If you want to set limits on files sizeyou can do it in the application.properties
:
如果要对文件大小设置限制,可以在以下位置进行application.properties
:
# File size limit
multipart.maxFileSize = 3Mb
# Total request size for a multipart/form-data
multipart.maxRequestSize = 20Mb
Moreover to send the file with Ajaxtake a look here: http://blog.netgloo.com/2015/02/08/spring-boot-file-upload-with-ajax/
此外,要使用Ajax发送文件,请看这里:http: //blog.netgloo.com/2015/02/08/spring-boot-file-upload-with-ajax/
回答by Ashutosh Jha
@Bean
MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize("5120MB");
factory.setMaxRequestSize("5120MB");
return factory.createMultipartConfig();
}
put it in class where you are defining beans
把它放在你定义 bean 的类中
回答by Ashutosh Jha
Latest version of SpringBoot makes uploading multiple filesvery easy also. On the browser side you just need the standard HTML upload form, but with multiple input elements(one per file to upload, which is very important), all having the same element name (name="files" for the example below)
最新版本的 SpringBoot 也使上传多个文件变得非常容易。在浏览器端,你只需要标准的 HTML 上传表单,但有多个输入元素(每个文件一个上传,这非常重要),所有元素都具有相同的元素名称(以下示例中的 name="files")
Then in your Spring @Controller class on the server all you needis something like this:
然后在服务器上的 Spring @Controller 类中,您只需要这样的东西:
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody ResponseEntity<?> upload(
@RequestParam("files") MultipartFile[] uploadFiles) throws Exception
{
...now loop over all uploadFiles in the array and do what you want
return new ResponseEntity<>(HttpStatus.OK);
}
Those are the tricky parts. That is, knowing to create multiple input elements each named "files", and knowing to use a MultipartFile[] (array) as the request parameter are the tricky things to know, but it's just that simple. I won't get into how to process a MultipartFile entry, because there's plenty of docs on that already.
这些是棘手的部分。也就是说,知道创建多个名为“files”的输入元素,并知道使用 MultipartFile[](数组)作为请求参数是很棘手的事情,但就是这么简单。我不会讨论如何处理 MultipartFile 条目,因为已经有很多关于它的文档。
回答by Vikki Kamboj
@RequestMapping(value="/add/image", method=RequestMethod.POST)
public ResponseEntity upload(@RequestParam("id") Long id, HttpServletResponse response, HttpServletRequest request)
{
try {
MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest)request;
Iterator<String> it=multipartRequest.getFileNames();
MultipartFile multipart=multipartRequest.getFile(it.next());
String fileName=id+".png";
String imageName = fileName;
byte[] bytes=multipart.getBytes();
BufferedOutputStream stream= new BufferedOutputStream(new FileOutputStream("src/main/resources/static/image/book/"+fileName));;
stream.write(bytes);
stream.close();
return new ResponseEntity("upload success", HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity("Upload fialed", HttpStatus.BAD_REQUEST);
}
}
回答by THIMIRA
In Controller, your method should be;
在控制器中,你的方法应该是;
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResponseEntity<SaveResponse> uploadAttachment(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
....
Further, you need to update application.yml (or application.properties) to support maximum file size and request size.
此外,您需要更新 application.yml(或 application.properties)以支持最大文件大小和请求大小。
spring:
http:
multipart:
max-file-size: 5MB
max-request-size: 20MB