如何在Jackson序列化时,当字段a为false时忽略字段b的序列化?
解决方案:Jackson序列化时根据其他字段值忽略指定字段
要实现当MyClass的a字段为false时忽略b字段的序列化,你之前用的@JsonInclude(Include.CUSTOM)只支持基于字段自身值的过滤,无法依赖其他字段,所以需要用以下两种方案:
方案一:使用@JsonIgnoreCondition(Jackson 2.12+ 推荐)
这个注解支持自定义忽略条件,能访问当前序列化对象的其他字段值。
1. 自定义忽略条件类
import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonIgnoreCondition; import com.fasterxml.jackson.databind.introspect.Annotated; import com.fasterxml.jackson.databind.introspect.AnnotatedField; public class IgnoreBWhenAFalseCondition implements JsonIgnoreCondition { @Override public boolean shouldIgnore(Annotated annotated, SerializerProvider provider) throws JsonMappingException { if (annotated instanceof AnnotatedField) { // 获取当前序列化的对象实例 Object instance = ((AnnotatedField) annotated).getOwner().getAnnotated().getInstance(); if (instance instanceof MyClass) { MyClass myObj = (MyClass) instance; // 当a为false时,返回true表示忽略b字段 return !myObj.isA(); } } return false; } }
2. 修改MyClass,给b字段加注解
public class MyClass { private boolean a; @JsonIgnore(condition = IgnoreBWhenAFalseCondition.class) private int b; // 必须提供getter方法,Jackson需要获取字段值和对象实例 public boolean isA() { return a; } public void setA(boolean a) { this.a = a; } public int getB() { return b; } public void setB(int b) { this.b = b; } }
测试验证
import com.fasterxml.jackson.databind.ObjectMapper; public class SerializationTest { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); MyClass objWithTrueA = new MyClass(); objWithTrueA.setA(true); objWithTrueA.setB(10); System.out.println(mapper.writeValueAsString(objWithTrueA)); // 输出:{"a":true,"b":10} MyClass objWithFalseA = new MyClass(); objWithFalseA.setA(false); objWithFalseA.setB(20); System.out.println(mapper.writeValueAsString(objWithFalseA)); // 输出:{"a":false} } }
方案二:使用BeanSerializerModifier(兼容低版本Jackson)
如果你的Jackson版本低于2.12,无法使用@JsonIgnoreCondition,可以通过修改序列化器逻辑实现:
1. 自定义序列化器修改器
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializationConfig; import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; import java.io.IOException; import java.util.List; public class MyClassSerializerModifier extends BeanSerializerModifier { @Override public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) { for (BeanPropertyWriter writer : beanProperties) { if ("b".equals(writer.getName())) { // 为b字段替换自定义序列化逻辑 writer.assignSerializer(new JsonSerializer<Integer>() { @Override public void serialize(Integer value, JsonGenerator gen, com.fasterxml.jackson.databind.SerializerProvider serializers) throws IOException { // 获取当前正在序列化的对象实例 MyClass currentObj = (MyClass) gen.getCurrentValue(); if (currentObj.isA()) { // 只有a为true时才序列化b gen.writeNumber(value); } } }); } } return beanProperties; } }
2. 注册修改器到ObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; public class SerializationTest { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); // 注册自定义修改器 mapper.registerModule(new SimpleModule() { @Override public void setupModule(SetupContext context) { super.setupModule(context); context.addBeanSerializerModifier(new MyClassSerializerModifier()); } }); // 测试代码同方案一,结果一致 } }
内容的提问来源于stack exchange,提问作者MiaoZi
相关产品推荐
相关产品推荐

