Jackson:使用类方法序列化POJO
可以!用Jackson自定义序列化器就能实现这个需求
Jackson的扩展性很强,完全能让它调用你类里自定义的toJSON()方法来完成序列化。我给你详细说下实现步骤和注意点:
1. 编写自定义JsonSerializer
这个序列化器会先判断对象是否实现了A接口,如果是就调用它的toJSON()方法,否则 fallback 到Jackson默认的序列化逻辑:
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.IOException; public class ToJsonMethodSerializer extends JsonSerializer<Object> { @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { if (value instanceof A) { // 调用自定义的toJSON()方法获取ObjectNode ObjectNode customJson = ((A) value).toJSON(); // 把ObjectNode写入JSON生成器 serializers.defaultSerializeValue(customJson, gen); } else { // 非A接口实现类,用Jackson默认序列化 serializers.defaultSerializeValue(value, gen); } } }
2. 注册序列化器到ObjectMapper
有三种注册方式,按需选择:
方式一:针对A接口注册(更高效)
只有实现了A接口的类才会使用这个序列化器,其他类不受影响:
ObjectMapper mapper = new ObjectMapper(); SimpleModule customModule = new SimpleModule(); // 把序列化器绑定到A接口 customModule.addSerializer(A.class, new ToJsonMethodSerializer()); mapper.registerModule(customModule);
方式二:全局注册(所有对象都会先检查是否实现A)
如果你的项目里大部分类都实现了A接口,可以用这种方式:
ObjectMapper mapper = new ObjectMapper(); SimpleModule customModule = new SimpleModule(); customModule.addSerializer(Object.class, new ToJsonMethodSerializer()); mapper.registerModule(customModule);
方式三:注解局部生效
不想修改全局ObjectMapper的话,直接在A接口或者Foo类上加@JsonSerialize注解:
@JsonSerialize(using = ToJsonMethodSerializer.class) public interface A { ObjectNode toJSON(); }
3. 关键注意事项
- 确保
Foo的toJSON()方法正确处理了父类Tokens的tokens字段,比如在实现时把父类的Map也加入到ObjectNode中:
@Override public ObjectNode toJSON() { ObjectNode node = JsonNodeFactory.instance.objectNode(); // 处理自身字段 node.put("id", this.id); node.set("bar", new ObjectMapper().convertValue(this.bar, ObjectNode.class)); // 处理父类的tokens字段 node.set("tokens", new ObjectMapper().convertValue(this.getTokens(), ObjectNode.class)); return node; }
- 如果
Bar类也实现了A接口,序列化时会自动递归调用它的toJSON()方法,非常方便。
验证效果
现在用配置好的ObjectMapper序列化Foo对象,就会自动调用它的toJSON()方法:
Foo foo = new Foo(); foo.setId(123L); foo.setBar(new Bar()); foo.getTokens().put("authToken", "abc123"); String jsonResult = mapper.writeValueAsString(foo); // 输出的JSON就是Foo的toJSON()方法生成的内容
内容的提问来源于stack exchange,提问作者Sterling Duchess
相关产品推荐
相关产品推荐

