@RequestPart 混合多部分请求,Spring MVC 3.2
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16230291/
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
@RequestPart with mixed multipart request, Spring MVC 3.2
提问by Raghvendra
I'm developing a RESTful service based on Spring 3.2. I'm facing a problem with a controller handling mixed multipart HTTP request, with a Second part with XMLor JSON formatted data and a second part with a Image file .
我正在开发基于 Spring 3.2 的 RESTful 服务。我面临一个控制器处理混合多部分 HTTP 请求的问题,第二部分带有 XML 或 JSON 格式的数据,第二部分带有图像文件。
I am using @RequestPart annotation for receiving the request
我正在使用@RequestPart 批注来接收请求
@RequestMapping(value = "/User/Image", method = RequestMethod.POST, consumes = {"multipart/mixed"},produces="applcation/json")
public
ResponseEntity<List<Map<String, String>>> createUser(
@RequestPart("file") MultipartFile file, @RequestPart(required=false) User user) {
System.out.println("file" + file);
System.out.println("user " + user);
System.out.println("received file with original filename: "
+ file.getOriginalFilename());
// List<MultipartFile> files = uploadForm.getFiles();
List<Map<String, String>> response = new ArrayList<Map<String, String>>();
Map<String, String> responseMap = new HashMap<String, String>();
List<String> fileNames = new ArrayList<String>();
if (null != file) {
// for (MultipartFile multipartFile : files) {
String fileName = file.getOriginalFilename();
fileNames.add(fileName);
try {
file.transferTo(new File("C:/" + file.getOriginalFilename()));
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
responseMap.put("displayText", file.getOriginalFilename());
responseMap.put("fileSize", "" + file.getSize());
response.add(responseMap);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Accept", "application/json");
return new ResponseEntity<List<Map<String, String>>>(response,
httpHeaders, HttpStatus.OK);
}
User.java will be like this-
User.java 会是这样的——
@XmlRootElement(name = "User")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private int userId;
private String name;
private String email;
private String company;
private String gender;
//getter setter of the data members
}
To my understanding, using the @RequestPart annotation I would expect the XML multipart section to be evaluated depending on its Content-Type and finally un-marshalled into my User class (I'm using Jaxb2, the marshaller/unmarhaller is properly configured in the application context and the procedure is working fine for all the other controller methods when I pass the XML data as body and use the @RequestBody annotation).
据我了解,使用 @RequestPart 注释,我希望根据其内容类型评估 XML 多部分部分,最后将其解组到我的用户类中(我使用的是 Jaxb2,编组器/解组器在当我将 XML 数据作为正文传递并使用 @RequestBody 注释时,应用程序上下文和过程对于所有其他控制器方法都可以正常工作)。
But what is actually happening is that, although the file is correctly found and parsed as MultipartFile, the "user" part is never seen and the request is always failing, not matching the controller method signature.
但实际发生的情况是,虽然文件被正确找到并解析为 MultipartFile,但从未看到“用户”部分并且请求总是失败,与控制器方法签名不匹配。
I reproduced the problem with several clients type and I am confident the format of the multipart request is ok.
我用几个客户端类型重现了这个问题,我相信多部分请求的格式没问题。
Please help me to solve this issue, Maybe some workaround will be there to receive mixed/multipart request.
请帮我解决这个问题,也许会有一些解决方法来接收混合/多部分请求。
Thanks and Regards,
感谢致敬,
Raghvendra
拉格文德拉
回答by Maksim
I have managed to solve the problem
我已经设法解决了这个问题
Endpoint example:
端点示例:
@PostMapping("/")
public Document create(@RequestPart Document document,
@RequestPart(required = false) MultipartFile file) {
log.debug("#create: document({}), file({})", delegation, file);
//custom logic
return document;
}
Exception:
例外:
"error_message": "Content type 'application/octet-stream' not supported"
Exception is thrown from the next method:
从下一个方法抛出异常:
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(HttpInputMessage,MethodParameter,Type)
Solution:
解决方案:
We have to create custom converter @Component, which implements HttpMessageConverteror HttpMessageConverterand knows about MediaType.APPLICATION_OCTET_STREAM. For simple workaround it's enough to extend AbstractHymanson2HttpMessageConverter
我们必须创建自定义转换器@Component,它实现HttpMessageConverter或HttpMessageConverter并且知道MediaType.APPLICATION_OCTET_STREAM。对于简单的解决方法,扩展AbstractHymanson2HttpMessageConverter就足够了
@Component
public class MultipartHymanson2HttpMessageConverter extends AbstractHymanson2HttpMessageConverter {
/**
* Converter for support http request with header Content-Type: multipart/form-data
*/
public MultipartHymanson2HttpMessageConverter(ObjectMapper objectMapper) {
super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
}
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return false;
}
@Override
public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
return false;
}
@Override
protected boolean canWrite(MediaType mediaType) {
return false;
}
}
回答by Tobin Schwaiger-Hastanan
Not sure if you had fixed your problem, but I also had a similar problem where my JSON object was not getting picked up by my controller when mixing @RequestPart and MultipartFile together.
不确定您是否解决了您的问题,但我也遇到了类似的问题,即在将 @RequestPart 和 MultipartFile 混合在一起时,我的 JSON 对象没有被我的控制器接收。
The method signature for your call looks correct:
您调用的方法签名看起来正确:
public ResponseEntity<List<Map<String, String>>> createUser(
@RequestPart("file") MultipartFile file, @RequestPart(required=false) User user) {
// ... CODE ...
}
However make sure your request looks something like this:
但是请确保您的请求如下所示:
POST /createUser
Content-Type: multipart/mixed; boundary=B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E
--B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E
Content-Disposition: form-data; name="user";
Content-Type: application/xml; charset=UTF-8
<user><!-- your user xml --></user>
--B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E
Content-Disposition: form-data; name="file"; filename="A551A700-46D4-470A-86E7-52AD2B445847.dat"
Content-Type: application/octet-stream
/// FILE DATA
--B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E--
回答by Pramod Wayabase
You can use @RequestPart from org.springframework.web.bind.annotation.RequestPart; It is used as Combining @RequestBody and file upload.
您可以使用 org.springframework.web.bind.annotation.RequestPart 中的 @RequestPart; 它用作结合@RequestBody 和文件上传。
Using @RequestParam like this @RequestParam("file") MultipartFile file you can upload only file and multiple single data (key value ) like
像这样使用@RequestParam @RequestParam("file") MultipartFile 文件,您可以只上传文件和多个单个数据(键值),例如
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
public void saveFile(
@RequestParam("userid") String userid,
@RequestParam("file") MultipartFile file) {
}
you can post JSON Object data and and File both using @RequestPart like
您可以使用@RequestPart 发布 JSON 对象数据和文件,例如
@RequestMapping(value = "/patientp", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<?> insertPatientInfo(
@RequestPart PatientInfoDTO patientInfoDTO,
@RequestPart("file") MultipartFile file) {
}
You are not limited to using multipart file uploads directly as controller method parameters. Your form objects can contain Part or MultipartFile fields, and Spring knows automatically that it must obtain the values from file parts and converts the values appropriately.
您不仅限于直接使用分段文件上传作为控制器方法参数。您的表单对象可以包含 Part 或 MultipartFile 字段,并且 Spring 自动知道它必须从文件部分获取值并适当地转换这些值。
Above method can respond to the previously demonstrated multipart request containing a single file. This works because Spring has a built-in HTTP message converter that recognizes file parts. In addition to the javax.servlet.http.Part type, you can also convert file uploads to org.springframework.web.multipart.MultipartFile. If the file field permits multiple file uploads, as demonstrated in the second multipart request, simply use an array or Collection of Parts or MultipartFiles.
上述方法可以响应前面演示的包含单个文件的多部分请求。这是有效的,因为 Spring 有一个内置的 HTTP 消息转换器来识别文件部分。除了 javax.servlet.http.Part 类型之外,您还可以将文件上传转换为 org.springframework.web.multipart.MultipartFile。如果文件字段允许多个文件上传,如第二个多部分请求中所示,只需使用数组或部分集合或 MultipartFiles。
@RequestMapping(value = "/patientp", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<?> insertPatientInfo(
@RequestPart PatientInfoDTO patientInfoDTO,
@RequestPart("files") List<MultipartFile> files) {
}
Happy To Help...
很高兴能帮助你...
回答by Erkan K?seo?lu
I have managed to solve problem:
我设法解决了问题:
@SuppressWarnings("rawtypes")
@RequestMapping(value = "/DataTransfer", method = RequestMethod.POST, produces = {
MediaType.APPLICATION_JSON_UTF8_VALUE }, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE} )
@ApiOperation(value = "Sbm Data Transfer Service", response = Iterable.class)
@ApiResponses(value = { @ApiResponse(code = 200, message = "Successfully find."),
@ApiResponse(code = 400, message = "There has been an error."),
@ApiResponse(code = 401, message = "You are not authorized to save the resource"),
@ApiResponse(code = 403, message = "Accessing the resource you were trying to reach is forbidden"),
@ApiResponse(code = 404, message = "The resource you were trying to reach is not found") })
ResponseEntity processDataTransfer(@RequestPart(name="file") MultipartFile file, @RequestPart(name="param") DataTransferInputDto param);
回答by rahul maindargi
have you tried
你有没有尝试过
ResponseEntity<List<Map<String, String>>> createUser(
@RequestPart("file") MultipartFile file, @RequestBody(required=false) User user) {
or
或者
ResponseEntity<List<Map<String, String>>> createUser(
@RequestPart("file") MultipartFile file, @RequestParam(required=false) User user) {
If this does not work can you show us mapping.xml
如果这不起作用,你能告诉我们吗 mapping.xml

