Jackson自定义序列化器调用类型错误问题求助
解决Jackson「Serializer called on wrong types」错误
嘿,这个问题我熟!你碰到的是Java泛型类型擦除带来的典型坑——Jackson没法准确识别你的FooSerializer应该处理的是List<Foo>而不是任意List类型,所以才会抛出类型不匹配的错误。
问题根源
你当前的序列化器构造函数用了Class<List<Foo>>作为参数,但Java在运行时会把泛型信息擦除,List<Foo>的实际类型就是List.class。这就导致Jackson要么把你的序列化器错误地应用到所有List类型(比如List<String>)上,要么反过来,处理List<Foo>时找不到对应的序列化器,最终触发类型错误。
修复方案
我们需要让Jackson明确知道这个序列化器是给List<Foo>用的,通过TypeReference来保留泛型信息,同时正确注册序列化器:
1. 修正自定义序列化器的构造函数
把原来依赖Class的构造改成用TypeReference,这样Jackson能保留泛型的类型信息:
public class FooSerializer extends StdSerializer<List<Foo>> { // 用TypeReference明确指定泛型类型,避免擦除问题 public FooSerializer() { super(new TypeReference<List<Foo>>() {}); } @Override public void serialize(List<Foo> foos, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeStartArray(foos.size()); for(Foo foo : foos){ gen.writeString(foo.getName()); } gen.writeEndArray(); } }
2. 正确注册序列化器
注册时不要直接用List.class,而是用Jackson的TypeFactory构造出List<Foo>的具体JavaType,确保Jackson能精准匹配:
ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); // 构造List<Foo>的JavaType,明确泛型参数 JavaType listFooType = mapper.getTypeFactory().constructCollectionType(List.class, Foo.class); module.addSerializer(listFooType, new FooSerializer()); mapper.registerModule(module);
备选方案:字段级直接指定(如果不需要全局注册)
如果只是某个实体类的特定字段需要用这个序列化器,可以直接在字段上用@JsonSerialize注解,这样不用全局注册也能生效:
public class YourEntity { // 直接指定该字段用FooSerializer处理 @JsonSerialize(using = FooSerializer.class) private List<Foo> foos; // getter、setter省略 }
验证要点
- 确保你的
Foo类有正确的getName()方法,避免序列化时出现空指针或其他异常 - 测试时可以尝试序列化一个
List<Foo>和一个普通List<String>,确认只有List<Foo>会触发你的自定义序列化逻辑
内容的提问来源于stack exchange,提问作者Urr4
相关产品推荐
相关产品推荐

