Jackson反序列化Map时出现No qualifying bean报错如何解决?
错误原因说明
- 第一个反序列化异常:你的
FilterDto中sectorFilter字段定义为Map<String, List<String>>类型,对应JSON结构应该是键值对对象({}包裹),但请求体中该字段传的是数组结构([]包裹),Jackson无法将数组反序列化为Map类型,因此抛出START_ARRAYtoken不匹配异常。 - 第二个Spring注入异常:你自定义的
FilterDeserializer只提供了带StdDeserializer<?>参数的构造方法,Jackson实例化反序列化器时会优先找无参构造方法,无可用无参构造时Spring会尝试按bean注入构造参数,但容器中没有对应类型的StdDeserializerbean,因此抛出注入失败异常。
解决方案
方案一:调整请求格式(优先推荐)
如果可以协调前端调整请求参数,直接去掉sectorFilter外层的数组包裹,请求体修改为如下结构即可,无需修改后端任何代码:
{ "sectorFilter": { "ab": [ "abc", "cde" ] } }
方案二:修复自定义反序列化器兼容数组格式
如果必须兼容现有请求格式,调整自定义反序列化器代码,补充无参构造方法并实现数组转Map的逻辑即可:
步骤1:重写反序列化器
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.node.ArrayNode; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; public class FilterDeserializer extends StdDeserializer<Map<String,List<String>>> { // 新增无参构造方法,指定反序列化目标类型 public FilterDeserializer() { super(Map.class); } @Override public Map<String,List<String>> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { Map<String, List<String>> resultMap = new HashMap<>(); // 读取数组节点 ArrayNode arrayNode = jsonParser.getCodec().readTree(jsonParser); // 遍历数组内的所有键值对对象,合并到结果Map arrayNode.forEach(itemNode -> { itemNode.fields().forEachRemaining(entry -> { // 重复key默认覆盖,如需合并List可自行调整逻辑 resultMap.put(entry.getKey(), deserializationContext.convertValue(entry.getValue(), List.class)); }); }); return resultMap; } }
步骤2:保留DTO字段注解
原有@JsonDeserialize注解无需修改:
@JsonDeserialize(using = FilterDeserializer.class) private Map<String, List<String>> sectorFilter;
内容的提问来源于stack exchange,提问作者Dilantha
相关产品推荐
相关产品推荐

