如何使用MockMvc解决MethodArgumentConversionNotSupportedException?

问题描述 投票:1回答:1

我正在写为一个接受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                                                                                                                                                                                                                        
spring-mvc mockito multipartform-data mockmvc
1个回答
-1
投票

你要改用@RequestPart @RequestParam的因为这是application/json请求的一部分。对于@RequestPart状态的Javadoc

支持的方法的参数类型包括MultipartFile与Spring的MultipartResolver抽象,javax.servlet.http.Part结合的Servlet 3.0多部分请求的同时,或以其它方式用于任何其他方法参数,该部分的内容是通过一个HttpMessageConverter考虑到“内容类型”头中传递的请求的一部分。这类似于@RequestBody确实解决基于非正规多请求的内容的论点是什么。

需要注意的是@RequestParam注释也可用于与一个方法参数支持相同方法参数类型一个“多部分/格式数据”请求的一部分相关联。主要的区别是,当该方法参数不是字符串,@RequestParam经由注册ConverterPropertyEditor依赖型转换而@RequestPart依赖于HttpMessageConverters考虑到请求部分的“内容类型”标头。 @RequestParam容易与名称 - 值形式领域中使用,而@RequestPart可能用含有更复杂的内容(例如JSON,XML)部分中使用。

想必,你还没注册Converter,也不是PropertyEditor,解析该部分的内容,而对于JSON的HttpMessageConverter时(取决于你的Spring MVC /引导版本),如果你有杰克逊在类路径中自动注册。

© www.soinside.com 2019 - 2024. All rights reserved.