如何通过Jackson注解实现私有变量的条件序列化(同键多类型)
用Jackson注解实现同一JSON键的动态类型序列化
先聊聊Jackson常规的序列化逻辑,你应该已经清楚,但再理一遍:
- 公共实例变量会直接以变量名为JSON键进行序列化,比如:
序列化后是:public List<String> myStrings = new ArrayList<>();{ "myStrings" : [ ... ] } - 私有实例变量如果有对应的公共
getVariable()风格的getter方法,也会以变量名为键序列化,比如:
序列化结果类似:private List<String> myStrings = new ArrayList<>(); public List<String> getMyStrings() { return myStrings; }{ "myStrings" : [ ... ] }
回到你的需求:你想通过一个开关变量firstStringOnly,让同一个JSON键myStrings在不同场景下分别输出字符串或者数组,还要靠@JsonInclude(NON_NULL)来自动屏蔽不符合条件的getter,而且完全不想用自定义序列化器。
当然可以实现! 只需要用Jackson的@JsonGetter注解配合你已经在用的@JsonInclude就能搞定,完全符合你的约束。
调整后的代码示例:
import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonInclude; import java.util.ArrayList; import java.util.List; @JsonInclude(JsonInclude.Include.NON_NULL) public class YourTargetClass { private boolean firstStringOnly = true; private List<String> myStrings = new ArrayList<>(); @JsonGetter("myStrings") public List<String> getMyStrings() { // 开关为true时返回null,会被NON_NULL过滤 return firstStringOnly ? null : myStrings; } @JsonGetter("myStrings") public String getFirstString() { // 开关为false时返回null,会被NON_NULL过滤;同时加个判空避免空指针 return firstStringOnly ? (myStrings.isEmpty() ? null : myStrings.get(0)) : null; } // 这里记得加上setter或者构造方法来初始化变量,比如: public void setFirstStringOnly(boolean firstStringOnly) { this.firstStringOnly = firstStringOnly; } public void addString(String s) { myStrings.add(s); } }
为什么这样能行?
@JsonGetter("myStrings")会把两个getter方法都绑定到同一个JSON键myStrings上;- 配合类上的
@JsonInclude(NON_NULL),Jackson会自动忽略返回null的getter方法; - 当
firstStringOnly=true时,getMyStrings()返回null被过滤,getFirstString()返回字符串,最终JSON里myStrings就是字符串类型; - 当
firstStringOnly=false时,getFirstString()返回null被过滤,getMyStrings()返回列表,最终JSON里myStrings就是数组类型。
注意事项
- 确保你的Jackson版本是2.12及以上(较新版本都支持这种同一个键绑定多个getter的场景);
- 给
getFirstString()加了判空逻辑,避免myStrings为空时抛出空指针异常,你可以根据自己的业务调整这部分; - 类上的
@JsonInclude会作用于所有属性,如果你只想针对myStrings这个键生效,也可以把注解单独加到两个getter方法上。
内容的提问来源于stack exchange,提问作者DVK
相关产品推荐
相关产品推荐

