【问题标题】:Jackson: How to edit existing property to the JSON without modifying the POJO?Jackson:如何在不修改 POJO 的情况下将现有属性编辑为 JSON?
【发布时间】:2020-09-15 19:43:59
【问题描述】:

我需要在 POJO 中编辑“现有字段”的名称,而不是添加“extra_field”。是否可以使用下面引用的方法链接?

请注意我不想使用@JsonProperty 注释。

要求是,我有一个 POJO,并且希望每次都使用不同的字段名称而不改变 POJO。例如,我在 POJO 中有一个字段c_id,有时它需要写为cust_id,而另一种时候它是my_id

另外请注意,我无法更改 POJO 的实现,因为它已经在多个模块中使用并且具有通用实现。

POJO 示例:

class MyPojo {
    String id; 
    // getter and setters
}

预期输出如下:(字段名称可以更改)

  1. {"cust_id": "123"}
  2. {"my_id": "123"}

【问题讨论】:

标签: java json jackson pojo


【解决方案1】:

混合

在不向原始 POJO 添加注释的情况下修改 Jackson 的输出的最简单方法是使用 mixins。

只需定义一个带有必要注释的 mixin 类,并向 Jackson 表明您想在序列化原始对象时使用该 mixin。

private static class MyPojoMixin {
    @JsonProperty("cust_id")
    private String id;
}

public String serializeWithMixin(MyPojo p) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.addMixIn(MyPojo.class, MyPojoMixin.class);

    return mapper.writeValueAsString(p);
}

自定义属性命名策略

如果您需要以编程方式更改字段名称,您可能无法使用 mixin 解决方案。然后,您可以使用自定义 PropertyNamingStrategy:

public class IdRenamingStrategy extends PropertyNamingStrategy {
    private final PropertyNamingStrategy inner;
    private final String newIdPropertyName;

    public IdRenamingStrategy(String newIdPropertyName) {
        this(PropertyNamingStrategy.LOWER_CAMEL_CASE, newIdPropertyName);
    }

    public IdRenamingStrategy(PropertyNamingStrategy inner, String newIdPropertyName) {
        this.inner = inner;
        this.newIdPropertyName = newIdPropertyName;
    }

    private String translate(String propertyName) {
        if ("id".equals(propertyName)) {
            return newIdPropertyName;
        } else {
            return propertyName;
        }
    }

    @Override
    public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
        return inner.nameForField(config, field, translate(defaultName));
    }

    @Override
    public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
        return inner.nameForGetterMethod(config, method, translate(defaultName));
    }

    @Override
    public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
        return inner.nameForSetterMethod(config, method, translate(defaultName));
    }

    @Override
    public String nameForConstructorParameter(MapperConfig<?> config, AnnotatedParameter ctorParam, String defaultName) {
        return inner.nameForConstructorParameter(config, ctorParam, translate(defaultName));
    }
}

可以这样使用:

public String serializeWithPropertyNamingStrategy(MyPojo p) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setPropertyNamingStrategy(new IdRenamingStrategy("cust_id"));

    return mapper.writeValueAsString(p));
}

【讨论】:

  • 这两个选项都对我有用。但是,第二个选项(自定义属性命名策略)一次仅适用于单个对象的一个​​字段。所以我选择了第一个(Mixins),它满足了我的需求。谢谢。
猜你喜欢
  • 2013-01-20
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-02
  • 2019-10-17
  • 2018-10-26
相关资源
最近更新 更多