【问题标题】:Jackson serialization duplicate field with @JsonAnyGetter杰克逊序列化重复字段与@JsonAnyGetter
【发布时间】:2021-04-02 19:10:55
【问题描述】:

我的 DTO 类具有预定义的字段和未映射的映射。当 otherFields 映射包含具有相同名称(field1 键)的字段时,杰克逊将它们都序列化,并且我有无效的 json,例如

{
"field1": "value",
"field1": "otherValue"
}
public class DTO implements Serializable {

    private String field1;

    @JsonIgnore
    @JsonAnySetter
    private final Map<String, Object> otherFields = new LinkedHashMap<>();

    @JsonAnyGetter
    public Map<String, Object> getOtherFields() {
        return otherFields;
    }

    public String getField1() {
        return field1;
    }

    public void setField1(String field1) {
        this.field1 = field1;
    }
}

在这种情况下有没有办法只选择一个值?对于我的情况,地图中的一个应该优先。

【问题讨论】:

  • 要实现这一点,您应该为您的 DTO 类实现 JsonSerializer,在 serialize 方法中编写您的逻辑
  • @AbhisekLamsal 还有其他复杂的选择吗?我的班级有很多具有相同问题的字段和嵌套对象
  • 我怀疑是否有任何其他方法可以解决您的特定问题。另一种选择是在所有字段中添加 JsonIgnore 并修改 getter 和 setter,以便您从 getter 中的映射返回值并在所有 setter 中向映射添加值。无论哪种方式,您都必须在此处自定义所有类

标签: java spring jackson jackson-databind


【解决方案1】:

我建议的最简单的解决方案是忽略属性,并在 getter 标记的 JsonAnyGetter 注释中添加额外的逻辑来检查这个条件:

class DTO {

    @JsonIgnore
    private String field1;

    private final Map<String, Object> otherFields = new LinkedHashMap<>();

    @JsonAnyGetter
    public Map<String, Object> getOtherFields() {
        otherFields.putIfAbsent("field1", field1);

        return otherFields;
    }

    @JsonAnySetter
    public void setOtherFields(String key, Object value) {
        otherFields.put(key, value);
    }

    public String getField1() {
        return field1;
    }

    public void setField1(String field1) {
        this.field1 = field1;
    }
}

这很简单,但是通过修改otherFields Map 来破坏getter。我们可以通过添加一个经典的getter 和一个Jackson 来改进它:

class DTO {

    private String field1;
    private final Map<String, Object> otherFields = new LinkedHashMap<>();

    @JsonIgnore
    public Map<String, Object> getOtherFields() {
        return otherFields;
    }

    @JsonAnyGetter
    private Map<String, Object> internalJacksonGetOtherFields() {
        otherFields.putIfAbsent("field1", field1);

        return otherFields;
    }

    @JsonAnySetter
    public void setOtherFields(String key, Object value) {
        otherFields.put(key, value);
    }

    @JsonIgnore
    public String getField1() {
        return field1;
    }

    public void setField1(String field1) {
        this.field1 = field1;
    }
}

【讨论】:

    猜你喜欢
    • 2013-08-16
    • 2012-02-25
    • 1970-01-01
    • 2021-12-02
    • 2013-07-10
    • 2014-05-05
    • 1970-01-01
    • 2015-05-18
    • 2021-06-18
    相关资源
    最近更新 更多