我正在写为一个接受MultipartFile
和自定义对象MessageAttachment
控制器方法的单元测试。到目前为止,我可以看到MultipartFile是请求的格式正确,但MessageAttachment不是。
该messageAttachment
的解析抛出与MethodArgumentConversionNotSupportedException
一个服务器端的500错误。
这似乎是一个问题,在测试中MessageAttachment转换为MockMultipartFile。这类似于图示例 - https://stackoverflow.com/a/21805186
题:
你怎么能解决与MockMvc一个MethodArgumentConversionNotSupportedException?
下测试控制器方法
@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
你要改用@RequestPart
@RequestParam
的因为这是application/json
请求的一部分。对于@RequestPart
状态的Javadoc
支持的方法的参数类型包括
MultipartFile
与Spring的MultipartResolver
抽象,javax.servlet.http.Part
结合的Servlet 3.0多部分请求的同时,或以其它方式用于任何其他方法参数,该部分的内容是通过一个HttpMessageConverter
考虑到“内容类型”头中传递的请求的一部分。这类似于@RequestBody
确实解决基于非正规多请求的内容的论点是什么。需要注意的是
@RequestParam
注释也可用于与一个方法参数支持相同方法参数类型一个“多部分/格式数据”请求的一部分相关联。主要的区别是,当该方法参数不是字符串,@RequestParam
经由注册Converter
或PropertyEditor
依赖型转换而@RequestPart
依赖于HttpMessageConverters
考虑到请求部分的“内容类型”标头。@RequestParam
容易与名称 - 值形式领域中使用,而@RequestPart
可能用含有更复杂的内容(例如JSON,XML)部分中使用。
想必,你还没注册Converter
,也不是PropertyEditor
,解析该部分的内容,而对于JSON的HttpMessageConverter
时(取决于你的Spring MVC /引导版本),如果你有杰克逊在类路径中自动注册。