Java使用Jackson序列化时如何移除JSON响应中的完全空对象
问题根因
- 你在
SpouseRes类上标注的@JsonInclude(Include.NON_NULL)只会过滤当前类内部值为null的字段,父类(如Client)中的spouse字段本身是已实例化的对象,不是null,因此Jackson会序列化这个对象,输出空对象{}而不是直接移除整个spouse字段。 - 你写的属性赋值逻辑存在明显错误:
if(Client.getSpouseRetireAge() != 0 || Client.getSpouseRetireAge() != null)的判断条件永远为真,不会进入else分支设null,导致数值类字段被设置为默认值0,进一步影响空对象判断。
修复步骤
1. 先修正属性赋值逻辑
把判断条件的||改为&&,逻辑才符合预期:
if(Client.getSpouseRetireAge() != null && Client.getSpouseRetireAge() != 0) { spouse.setRetireAge(Client.getSpouseRetireAge()); } else { spouse.setRetireAge(null); }
2. 实现空对象全局过滤,按需选择以下任意一种方案即可
方案一:自定义Jackson值过滤器(无侵入,推荐)
给SpouseRes类配置自定义空值过滤器,让Jackson识别空实例并直接过滤外层字段:
// 自定义过滤器类 public class SpouseResFilter { @Override public boolean equals(Object obj) { // 返回true时Jackson会过滤当前字段 if (obj == null) return true; if (obj instanceof SpouseRes) { return ((SpouseRes) obj).isEmpty(); } return false; } } // 替换SpouseRes类上的@JsonInclude注解 @Getter @Setter @Data @JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = SpouseResFilter.class) public class SpouseRes implements Serializable { // 原有代码保持不变 }
方案二:业务层直接设空(最简单)
如果不需要通用适配,直接在业务逻辑中判断SpouseRes是否为空,为空时直接给Client的spouse字段设null即可,你原有的NON_NULL配置会自动过滤null字段:
if (spouse.isEmpty()) { client.setSpouse(null); } else { client.setSpouse(spouse); }
方案三:使用NON_EMPTY配置(需适配自定义空判断)
如果要使用Jackson自带的NON_EMPTY规则,需要确保Jackson能识别你自定义的isEmpty()方法,在SpouseRes类上添加@JsonInclude(JsonInclude.Include.NON_EMPTY),同时给isEmpty()方法添加@JsonProperty注解让Jackson识别即可。
注意事项
你当前用Lombok的@Data生成的equals方法会比对所有字段,若salary字段是实例化后的空SalaryResponse对象,会导致isEmpty()返回false,需要根据业务场景调整isEmpty()的判断逻辑,把内部空对象的场景也纳入判断。
内容的提问来源于stack exchange,提问作者Masoom Raza
相关产品推荐
相关产品推荐

