Java SpringBoot 满足指定条件时不返回特定null字段问题咨询
SpringBoot API JSON返回字段条件隐藏解决方案
以下两种方案均可实现需求,不会过滤其他字段的null值,无需使用全局@JsonInclude(Include.NON_NULL)注解。
方案1:自定义Jackson序列化器(推荐,侵入性低)
通过自定义序列化规则直接控制Details结构的输出逻辑:
- 编写
Details类的专属序列化器
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import java.io.IOException; public class DetailsSerializer extends StdSerializer<Details> { // 无参构造器必须保留 public DetailsSerializer() { super(Details.class); } @Override public void serialize(Details details, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeStartObject(); // 固定输出message字段 gen.writeStringField("message", details.getMessage()); // 仅当message不是未找到提示时,输出loaded字段(哪怕值为null也会正常输出) if (!"not found in database".equals(details.getMessage())) { gen.writeObjectField("loaded", details.getLoaded()); } // 若Details有其他字段,可在此处依次添加序列化逻辑 gen.writeEndObject(); } }
- 给
Details类绑定序列化器
import com.fasterxml.jackson.databind.annotation.JsonSerialize; @JsonSerialize(using = DetailsSerializer.class) public class Details { private String message; // 按你实际业务修改loaded字段的类型,支持任意类型 private Object loaded; // 其他字段、Getter、Setter方法省略 }
方案2:业务层构造DTO时处理(逻辑直观,无需额外Jackson配置)
在构造返回结果时分场景处理:
- 数据库查询到匹配记录时:正常给
Details对象的loaded字段赋值(即使数据库存储为null也正常set null) - 未查询到匹配记录时:仅给
Details对象的message字段赋值,loaded字段设置为自定义的特殊标记值,配合@JsonInclude过滤该标记值即可
代码示例:
import com.fasterxml.jackson.annotation.JsonInclude; public class Details { // 定义特殊标记,仅用于未查询到场景的loaded字段赋值 public static final Object LOADED_HIDE_MARKER = new Object(); private String message; // 当loaded值为LOADED_HIDE_MARKER时不序列化该字段 @JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = HideFilter.class) private Object loaded; // 过滤规则内部类 static class HideFilter { @Override public boolean equals(Object obj) { // 匹配到标记值则返回true,触发字段过滤 return LOADED_HIDE_MARKER.equals(obj); } } // 其他字段、Getter、Setter方法省略 }
业务层构造逻辑示例:
public Details getDetailFromDb(String queryParam) { Details res = new Details(); Record record = dbMapper.selectOne(queryParam); if (record == null) { res.setMessage("not found in database"); // 未查询到场景设置标记值,触发字段隐藏 res.setLoaded(Details.LOADED_HIDE_MARKER); return res; } res.setMessage("query success"); // 正常赋值,哪怕record.getLoaded()为null也会正常返回loaded: null res.setLoaded(record.getLoaded()); return res; }
内容的提问来源于stack exchange,提问作者nosalahmoproblem
相关产品推荐
相关产品推荐

