如何使用MockMvc解决MethodArgumentConversionNotSupportedException? [英] How to resolve MethodArgumentConversionNotSupportedException with MockMvc?
问题描述
我正在为接受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
受支持的方法参数类型一起包括
MultipartFile
使用Spring的MultipartResolver
抽象,javax.servlet.http.Part
与Servlet 3.0 multipart一起使用 请求或其他任何方法参数的内容 该零件通过HttpMessageConverter
传递给 请考虑请求部分的"Content-Type"标头.这是 类似于@RequestBody
所做的基于 非分段常规请求的内容.
Supported method argument types include
MultipartFile
in conjunction with Spring'sMultipartResolver
abstraction,javax.servlet.http.Part
in conjunction with Servlet 3.0 multipart requests, or otherwise for any other method argument, the content of the part is passed through anHttpMessageConverter
taking into consideration the 'Content-Type' header of the request part. This is analogous to what@RequestBody
does to resolve an argument based on the content of a non-multipart regular request.
请注意,@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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!