Bootstrap

Spring MVC传递List类型参数报错:No primary or default constructor found for interface java.util.List]使用两种注解解决

  • 在测试GenericConverter传递List数组的时候,出现No primary or default constructor found for interface java.util.List] with r这个错误
  • 解决
  1. 因为报错是500所以肯定是后端的问题,看一下报错记录
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Apr 21 18:27:57 CST 2020
There was an unexpected error (type=Internal Server Error, status=500).
No primary or default constructor found for interface java.util.List
  1. 再看控制台报错
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: No primary or default constructor found for interface java.util.List] with root cause
  1. 简便一下
Request processing failed
  1. 请求处理失败,具体的失败是后面:No primary or default constructor found for interface java.util.List] with root cause
    因为是在自定义数组转换器的时候失败的,所以我还是去自定义转换器那里加了一个断点,发现不是在参数转换过程中失败。

  2. 所以应该是处理器处理参数之前的步骤出错了。确定处理器之前的步骤就是HandlerMapping进行请求与@RequestMapping的匹配了。
    那么就可能不是一个单例,而是可能是一个普遍性问题,我们去掉自定义转化器,写一个简单的控制器

    @GetMapping("/no/list")
    @ResponseBody
    public List<String> lists(  List<String> strs){
        return strs;
    }

结果:

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Apr 21 18:42:29 CST 2020
There was an unexpected error (type=Internal Server Error, status=500).
No primary or default constructor found for interface java.util.List

哈哈哈,说明这是一个一般性的问题。

  1. 那就咱进一步,因为获取控制器参数是在进入控制器方法之前(因为需要转换成控制器所需要的参数),所以肯定是在获取控制器参数之前。
    那就是处理器映射过程中的问题了。
    处理器映射需要把请求路径与@RequestMapping匹配,现在看来这个过程还需要对参数进行映射。

  2. 但是我突然想到无注解之下SPring MVC获取参数的唯一要求是参数名称与Http请求参数名称保持一致,一般的List参数简单的用逗号隔开就可以了,不会有所谓的名称,那就可能是这样导致的。
    那我加上名称试一试

http://localhost:8243/role/no/list?strs=1,2,3

还是报错

  1. 原谅我这个时候又想到一点,逗号隔开是数组的默认传递方式,不是list啊
    也就是名称匹配但是,但是目标对象不匹配。
    那就试试改成数组
    @GetMapping("/no/array")
    @ResponseBody
    public String[] lists(  String[] strs){
        return strs;
    }

结果是可以的
9. 所以我暂时给他定一个结论,就是不匹配
那就用@RequestParam让他强制匹配

    @GetMapping("/no/list")
    @ResponseBody
    public List<String> lists(  @RequestParam List<String> strs){
        return strs;
    }

可以了!!!!!!
10. 嘿嘿,那么我的问题就解决了,不过List还是使用JSON传递的比较多
所以在试一试@RequestBody,但是我不会写这种前端的,再等前端抽一个例子给我

;