Java反序列化报无法从START_OBJECT token实例化ArrayList错误怎么解决
报错原因
- 核心问题:调用
objectMapper.convertValue(response, new TypeReference<List<com.abc.second.model.CarType>>() {})时,传入的response参数对应的JSON结构是对象类型(用{}包裹),但你指定的反序列化目标是List集合类型(对应JSON应为[]包裹的数组),类型不匹配直接触发反序列化失败。 - 常见触发场景:接口返回的车型列表不是直接放在根节点的数组,而是被包裹在外层对象的某个字段中,比如返回结构为
{"code":200,"msg":"success","data":[{"id":1,"name":"轿车"},...]},你直接把整个外层对象传给了convertValue方法,而不是提取其中的数组字段。 - 其他排查点:如果确认response理论上应该是数组,可检查接口空列表场景下的返回值,部分接口空列表时会返回
{}而非[],也会触发该报错。
可行解决方案
- 方案1:调整反序列化结构匹配实际返回值
先调试获取response对应的完整JSON结构,假设列表嵌套在外层对象的data字段中,先定义外层响应类:
再修改工具类的转换逻辑:// 匹配接口根返回结构的响应类 public class CarTypeResponse { private List<com.abc.second.model.CarType> data; public List<com.abc.second.model.CarType> getData() { return data; } public void setData(List<com.abc.second.model.CarType> data) { this.data = data; } }public static java.util.List<com.abc.first.model.CarType> getCarTypes(Object response) { // 先转换为外层响应对象,再提取内部数组 CarTypeResponse resp = objectMapper.convertValue(response, CarTypeResponse.class); java.util.List<com.abc.second.model.CarType> sourceList = resp.getData(); java.util.List<com.abc.first.model.CarType> resultList = new java.util.ArrayList<>(); for (com.abc.second.model.CarType hmbModel : sourceList) { com.abc.first.model.CarType mobModel = new com.abc.first.model.CarType(); mobModel.setId(hmbModel.getId()); mobModel.setName(hmbModel.getName()); resultList.add(mobModel); } return resultList; } - 方案2:配置Jackson兼容单对象转数组
如果存在接口有时返回单个对象、有时返回数组的场景,可给ObjectMapper开启兼容配置:
开启后遇到单个对象反序列化为List的场景时,Jackson会自动将对象包装为单元素集合,避免报错。objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); - 方案3:空返回兼容处理
如果仅空列表场景下接口返回空对象,可在转换前先判断response的结构,若为空对象直接返回空集合,再走正常转换逻辑即可。
内容的提问来源于stack exchange,提问作者Syed ibrahim
相关产品推荐
相关产品推荐

