如何在Jackson中为Alpha类重写JsonInclude.NON_EMPTY的空对象检查逻辑
解决Jackson中Alpha类空对象序列化问题
问题场景
现有两个标注了@JsonInclude(JsonInclude.Include.NON_EMPTY)注解的Java类:
@JsonInclude(JsonInclude.Include.NON_EMPTY) @Data class Alpha { String a; String b; String c; } @JsonInclude(JsonInclude.Include.NON_EMPTY) @Data class Gamma { String xxx; Alpha alpha; String yyy; }
当Gamma作为API响应实例化如下时:
Gamma gamma = new Gamma(); gamma.setXxx("val1"); gamma.setYyy("val2"); gamma.setAlpha(new Alpha()); // 该Alpha的所有属性均为null
API客户端收到的响应为:
{ "xxx": "val1", "yyy": "val2", "alpha":{} }
其中空的alpha字段不符合预期,虽理想方案是避免初始化属性全为null的Alpha对象,但实际业务场景中无法避免此类情况,需要针对Alpha类重写Jackson在JsonInclude.Include.NON_EMPTY注解下的空对象检查逻辑。
解决方案
方法1:为Alpha类手动实现isEmpty()方法
Jackson处理NON_EMPTY规则时,会优先调用对象的isEmpty()方法判断是否为空。由于Lombok的@Data注解不会自动生成该方法,我们可以手动为Alpha类添加自定义逻辑,定义“空对象”的判定标准:
@JsonInclude(JsonInclude.Include.NON_EMPTY) @Data class Alpha { String a; String b; String c; // 自定义空对象判定:所有属性均为null时,视为空 @Override public boolean isEmpty() { return a == null && b == null && c == null; } }
配置后,Jackson序列化Gamma对象时会调用Alpha的isEmpty()方法,返回true时会忽略alpha字段,最终响应变为:
{ "xxx": "val1", "yyy": "val2" }
方法2:使用Jackson自定义值过滤器(无需修改实体类)
如果无法改动Alpha类的代码,可以通过自定义过滤器实现空对象判断:
- 创建空对象检查器:
public class AlphaEmptyChecker implements Predicate<Object> { @Override public boolean test(Object obj) { if (!(obj instanceof Alpha)) { return false; } Alpha alpha = (Alpha) obj; return alpha.getA() == null && alpha.getB() == null && alpha.getC() == null; } }
- 在ObjectMapper中配置该过滤器:
ObjectMapper mapper = new ObjectMapper(); mapper.setDefaultPropertyInclusion(JsonInclude.Value.construct( JsonInclude.Include.NON_EMPTY, JsonInclude.Include.ALWAYS ).withValueFilter(new AlphaEmptyChecker()));
方法3:结合Lombok特性实现空判断
如果想利用Lombok生成的方法,可通过对象比较间接实现空检查:
@JsonInclude(JsonInclude.Include.NON_EMPTY) @Data class Alpha { String a; String b; String c; public boolean isEmpty() { // 与默认构造的空对象比较,判定当前对象是否为空 return this.equals(new Alpha()); } }
注意:该方式要求所有属性的默认值为null,若属性有其他默认值需调整比较逻辑。
内容的提问来源于stack exchange,提问作者ThrowableException
相关产品推荐
相关产品推荐

