本文介绍了如何使用MockMvc解决MethodArgumentConversionNotSupportedException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为接受MultipartFile的控制器方法编写单元测试和自定义对象MessageAttachment.到目前为止,我可以看到MultipartFile是请求的正确格式,但MessageAttachment不是.

I'm writing a unit test for a controller method that accepts a MultipartFileand 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依赖于类型 通过注册的ConverterPropertyEditor进行转换 @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).

大概您没有注册ConverterPropertyEditor来解析该部分的内容,而如果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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 05:19