使用@RequestBody Map<String,Object>接受JSON,数组却变成了Arraylist,这是为什么?

在Controller 中写了个方法:

 @PostMapping("/test1")
public String test1(@RequestBody Map<String,Object> map){
    //String[] imgs = (String[]) map.get("imgs"); //java.lang.ClassCastException: java.util.ArrayList cannot be cast to [Ljava.lang.String;
    ArrayList<String> imgs = (ArrayList<String>) map.get("imgs");
    String name = (String) map.get("name");
    String str1 = "";

    for (String str: imgs) {
        System.err.println(str);
        str1 = str1+"参数:"+str+"\n";
    }
    return "姓名:"+name+"\n"+str1;
}

请求内容:

    {
"name": "weiwei",
"imgs": [
    "abc",
    "123",
    "/*-"
]

}

如果我使用
    String[] imgs = (String[]) map.get("imgs")
去获取传过来的数组就会报错:
java.lang.ClassCastException: java.util.ArrayList cannot be cast to [Ljava.lang.String;
说ArrayList不能转换成String[];
我JSON中的内容传的是一个数组呀,为什么变成ArrayList了?
阅读 16.5k
2 个回答

这是因为Jackson对于 Array 类型反序列化时默认转换为 ArrayList 类型
如果需要转换为 Array 类型,你需要对 ObjectMapper 对象进行配置
如:

ObjectMapper mapper = new ObjectMapper();
// USE_JAVA_ARRAY_FOR_JSON_ARRAY JSON中的Array类型转换为Java中的Array类型,true为转换为Array类型,false转换为ArrayList类型(默认)
mapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
Map<String, Object> map = mapper.readValue("{\"arr\":[1,2]}", Map.class);
System.out.println(map.get("arr").getClass());// class [Ljava.lang.Object;
System.out.println(Arrays.toString((Object[]) map.get("arr")));// [1, 2]

对于 ObjectMapper 的其他配置参考 https://ketao1989.github.io/2...
如果是在Spring Boot项目,可以这样配置

@RestController
@SpringBootApplication
public class Application {

    @RequestMapping(value = "/json")
    public Map<String, Object> json(@RequestBody Map<String, Object> body) {
        for (Map.Entry<String, Object> entry : body.entrySet()) {
            System.out.println(entry.getKey() + "的value类型为:" + entry.getValue().getClass());
        }
        return body;
    }

    public static void main(String[] args) {
        SpringApplication.run(Application .class, args);
    }

    @Configuration
    class JacksonConfiguration {
        @Bean
        public ObjectMapper objectMapper() {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
            return objectMapper;
        }
    }
}

其他方式配置可以查看 https://gxnotes.com/article/1...

@RequsetBody会读取request的body数据,之后会调用MappingJackson2HttpMessageConverter解析数据,会使用到ObjectMapper,之后this.objectMapper.readValue(inputMessage.getBody(), javaType);javaType是
AbstractJackson2HttpMessageConverter中getJavaType优选出来可以解析context的类型.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题