You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jackson如何仅序列化指定字段?解决ORM递归序列化问题

解决Jackson仅序列化指定字段+处理循环引用的方案

嘿,刚好处理过类似的场景,给你两个精准的解决方案,分别搞定「仅序列化指定字段」和「循环引用序列化」的问题:

一、仅序列化带有指定注解的字段

默认Jackson会序列化所有可访问的字段/getter方法,要实现默认忽略所有,只序列化带指定标记的字段,有两种常用方式:

方式1:使用@JsonView(推荐,代码侵入性低)

  1. 先定义一个标记用的空接口,用来区分需要序列化的字段:
public interface SerializeView {}
  1. 在你需要导出的字段(或对应的getter方法)上标注@JsonView(SerializeView.class):
public class ExternalClass {
    // 这个字段会被序列化
    @JsonView(SerializeView.class)
    private String neededField1;
    
    // 这个字段会被序列化
    @JsonView(SerializeView.class)
    private Integer neededField2;
    
    // 其他大量字段默认被忽略
    private String ignoreField1;
    private Long ignoreField2;
    // ... 更多无需导出的字段
}
  1. 序列化时指定使用这个View,同时关闭默认View包含规则:
ObjectMapper mapper = new ObjectMapper();
// 关键配置:只有标注了指定View的字段才会被序列化
mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
String json = mapper.writerWithView(SerializeView.class).writeValueAsString(externalObj);

方式2:使用@JsonProperty配合全局配置(更彻底)

如果你不想用View,也可以通过全局配置让Jackson默认忽略所有字段,只序列化带有@JsonProperty注解的字段:

ObjectMapper mapper = new ObjectMapper();
// 设置默认行为:仅序列化标注了@JsonProperty的字段
mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()
        .withFieldVisibility(JsonAutoDetect.Visibility.NONE)
        .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
        .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
        .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));

然后在需要序列化的字段上标注@JsonProperty即可:

public class ExternalClass {
    @JsonProperty
    private String neededField1;
    
    @JsonProperty
    private Integer neededField2;
    
    // 其他字段默认被忽略
}

二、解决ORM循环引用的序列化问题

对于A->B->A->B的递归关联,有三种常用解法:

方式1:@JsonManagedReference + @JsonBackReference(推荐双向关联场景)

在双向关联的两端分别标注这两个注解,主动端正常序列化,被动端被忽略:

public class ClassA {
    @JsonManagedReference // 主动关联端,正常序列化
    private ClassB b;
}

public class ClassB {
    @JsonBackReference // 被动关联端,序列化时被忽略,避免循环
    private ClassA a;
}

方式2:@JsonIgnore(简单粗暴,单向忽略)

直接在导致循环的字段上标注@JsonIgnore,比如在ClassB的a字段上标注,这样序列化ClassA时不会递归序列化ClassB里的a:

public class ClassB {
    @JsonIgnore
    private ClassA a;
}

方式3:@JsonIdentityInfo(保留关联关系,适合需要展示ID的场景)

如果需要保留对象的关联关系(比如序列化时用ID代替重复对象),可以用这个注解:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ClassA {
    private Long id;
    private ClassB b;
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ClassB {
    private Long id;
    private ClassA a;
}

这样序列化时,第一次出现的对象会完整输出,后续重复出现的同一对象会用ID代替,既避免循环又保留了关联关系。

内容的提问来源于stack exchange,提问作者Lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 21:12:52