问题描述
我正在为接受MultipartFile
的控制器方法编写单元测试和自定义对象MessageAttachment
.到目前为止,我可以看到MultipartFile是请求的正确格式,但MessageAttachment不是.
I'm writing a unit test for a controller method that accepts a MultipartFile
and a custom object MessageAttachment
. So far I can see that the MultipartFile is the correct format for the request but the MessageAttachment is not.
messageAttachment
的解析会引发MethodArgumentConversionNotSupportedException
的服务器端500错误.
The parsing of the messageAttachment
throws a server side 500 error with MethodArgumentConversionNotSupportedException
.
在测试中将MessageAttachment转换为MockMultipartFile似乎是一个问题.这类似于此处显示的示例- https://stackoverflow.com/a/21805186
It seem to be an issue with converting the MessageAttachment to a MockMultipartFile in the test. This is similar to the example shown here - https://stackoverflow.com/a/21805186
问题:
如何使用MockMvc解决MethodArgumentConversionNotSupportedException?
How can you resolve a MethodArgumentConversionNotSupportedException with MockMvc?
正在测试的控制器方法
@RequestMapping(value = "/", method = RequestMethod.POST, consumes = "multipart/form-data", produces = "application/json")
public ResponseEntity<MessageAttachment> handleFileUpload(@RequestParam(value = "file", required = true) MultipartFile file, @RequestParam(value = "messageAttachment") MessageAttachment messageAttachment) {
//do stuff with the file and attachment passed in..
MessageAttachment attachment = new MessageAttachment();
return ResponseEntity.accepted().header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + file.getOriginalFilename() + "\"").body(attachment);
}
MockMvc测试
@Test
public void shouldSaveUploadedFile() throws Exception {
// Given
ObjectMapper mapper = new ObjectMapper();
MessageAttachment messageAttachment = new MessageAttachment();
messageAttachment.setTimestamp(new Date());
MockMultipartFile multipartFile = new MockMultipartFile("file", "test.txt", "text/plain",
"Spring Framework".getBytes());
//Mapping the msgAttachment to a MockMultipartFile HERE
MockMultipartFile msgAttachment = new MockMultipartFile("messageAttachment", "","application/json",
mapper.writeValueAsString(messageAttachment).getBytes());
// When
this.mockMvc.perform(MockMvcRequestBuilders.multipart("/media/")
.file(multipartFile)
.file(msgAttachment)).andDo(MockMvcResultHandlers.print());
}
MockMvcResultHandlers.print()的控制台输出
MockHttpServletRequest:
HTTP Method = POST
Request URI = /media/
Parameters = {}
Headers = {Content-Type=[multipart/form-data]}
Body = <no character encoding set>
Session Attrs = {}
Handler:
Type = com.fizz.buzz.fizzapi.controller.MediaUploadController
Method = public org.springframework.http.ResponseEntity<com.fizz.buzz.fizzapi.model.MessageAttachment> com.fizz.buzz.fizzapi.controller.MediaUploadController.handleFileUpload(org.springframework.web.multipart.Mu
ltipartFile,com.fizz.buzz.fizzapi.model.MessageAttachment,javax.servlet.http.HttpServletRequest)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException
ModelAndView:
View name = null
View = null
Model = null
推荐答案
对于部分为application/json
的请求,您将希望使用@RequestPart
而不是@RequestParam
. @RequestPart
状态的Javadoc
You'll want to use @RequestPart
instead of @RequestParam
for the part of the request that is application/json
. The javadoc for @RequestPart
states
请注意,@RequestParam
批注也可以用于关联 带有方法参数的"multipart/form-data"请求的一部分 支持相同的方法参数类型. 主要区别在于 当方法参数不是字符串时,@RequestParam
依赖于类型 通过注册的Converter
或PropertyEditor
进行转换 @RequestPart
依赖HttpMessageConverters
请求部分的"Content-Type"标头. @RequestParam
与名称-值表单字段一起使用,而@RequestPart
可能会 与包含更复杂内容(例如JSON,XML)的部分一起使用.
Note that @RequestParam
annotation can also be used to associate the part of a "multipart/form-data" request with a method argument supporting the same method argument types. The main difference is that when the method argument is not a String, @RequestParam
relies on type conversion via a registered Converter
or PropertyEditor
while @RequestPart
relies on HttpMessageConverters
taking into consideration the 'Content-Type' header of the request part. @RequestParam
is likely to be used with name-value form fields while @RequestPart
is likely to be used with parts containing more complex content (e.g. JSON, XML).
大概您没有注册Converter
或PropertyEditor
来解析该部分的内容,而如果JSON HttpMessageConverter
会自动注册(取决于您的Spring MVC/Boot版本),如果你在课程路径上有杰克逊.
Presumably, you haven't registered a Converter
, nor a PropertyEditor
, to parse the content of that part, whereas an HttpMessageConverter
for JSON is automatically registered (depending on your Spring MVC/Boot version) if you have Jackson on the classpath.
这篇关于如何使用MockMvc解决MethodArgumentConversionNotSupportedException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!