【问题标题】:How to map JSON field names to different object field names?如何将 JSON 字段名称映射到不同的对象字段名称?
【发布时间】:2012-04-02 05:23:11
【问题描述】:

Jackson json 注释中以下 jax-b 注释的等效方式是什么?

我需要生成 json 而不是 xml,并且需要知道在 jax-b 中等效表示的常规杰克逊注解。

  1. 重命名字段。
  2. 使用 getter 代替字段。

如果 json/xml 元素名称是 java 保留字,这些特性尤其重要 比如“new”、“public”、“static”等

因此我们必须将 POJO 字段分别命名为“_new_”、“_public_”、“_static_”等,

但使用 jax-b 注释将它们重命名为“new”、“public”、“static”等 在生成的 XML(和 json)元素中。

重命名字段

@XmlAccessorType(XmlAccessType.FIELD)
public class Person{
    @XmlElement(required = true)
    protected String name;
    @XmlElement(required = true)
    protected String address;
    @XmlElement(name = "contractor")
    protected boolean _restricted_ ;
    @XmlElement(name = "new")
    protected boolean _new_ ;
}

重定向到使用属性getter(我认为这是在jax-b中完成的)

@XmlAccessorType(XmlAccessType.PROPERTY)
public class Person{
    protected String name;
    protected String address;
    protected boolean _restricted_ ;
    protected boolean _new_ ;

    @XmlElement(required = true)
    protected String getName() {return name;}
    @XmlElement(required = true)
    protected String getAddress() {return address;}
    @XmlElement(name = "contractor")
    protected boolean getRestricted() {return _restricted_;}
    @XmlElement(name = "new")
    protected boolean getNew(){return _new_;}
}

【问题讨论】:

  • @XmlElement(name = "new") 不适合您吗?我刚刚在 Jersey servlet(使用 Jackson)上试了一下,效果很好。
  • 我正在使用 RestyGWT - 我认为在 RestyGWT 中找不到该功能,因此在尝试/提议提交补丁之前我需要知道 jackson equiv。
  • 感谢@BlessedGeek 的提示。可以在wiki.fasterxml.com/AnnotationIntrospector 找到更多信息尽管链接中的方法有点旧,但我正在使用此代码来设置序列化器/反序列化器的优先级。 objectMapper.setAnnotationIntrospector(new AnnotationIntrospectorPair(new JacksonAnnotationIntrospector(), new JaxbAnnotationIntrospector()));

标签: java xml json annotations jackson


【解决方案1】:

可能有点晚了,但无论如何..

你可以重命名一个属性,只需添加

@JsonProperty("contractor")

默认情况下,Jackson 使用 getter 和 setter 进行序列化和反序列化。

更多详细信息:http://wiki.fasterxml.com/JacksonFAQ

【讨论】:

  • 我可以在已经用 @XmlElement 注释的 Person 类中使用这个 @JsonProperty 注释吗?我试图覆盖这样的属性值:@JsonProperty(value = "json_Name") @XmlElement(name = "name_provider") public String getName() { return name; } 但无论如何我的名称值是 name_provider,而不是 json_Name
  • 是的,尽管它是否有效取决于包含的 `AnnotationIntrospector's 的优先级(杰克逊自己的 vs JAXB)。两者都将被检测到,但以更高优先级注册的“获胜”。
  • 感谢@StaxMan 的提示。我使用here 找到的编码来设置优先级
【解决方案2】:

举个例子,你也可以在getter和setter中使用它来重命名为不同的字段

public class Sample {

    private String fruit;

    @JsonProperty("get_apple")
    public void setFruit(String fruit) {
        this.fruit = fruit;
    }

    @JsonProperty("send_apple")
    public String getFruit() {
        return fruit;
    }

}

【讨论】:

    【解决方案3】:

    请注意,正确的 JavaEE API 是使用 javax.json.bind.annotation.JsonbProperty 注释。当然 Jackson 和其他人只是 JSON Binding API 的一些实现,他们很可能会遵守这一点。

    【讨论】:

      【解决方案4】:

      如果您不使用 Jackson 仍想重命名属性,您可以使用 @SerializedName("your_original_key_name")

      我的 JSON 数据:

      {
        "default": "0"
      }
      

      如您所知,我们从不使用预定义的关键字作为变量名,因此解决方案是:

      @SerializedName("default")
      private String default_value;
      
      public String getDefault_value() {
              return default_value;
          }
      public void setDefault_value(String default_value) {
              this.default_value = default_value;
          }
      

      这就是你现在需要做的所有事情,值来自键“default”,你可以将它与 getter 和 setter 一起使用,使用“default_value”

      在这种情况下(Predifind 关键字作为 Json 键名),或者在您想要更改变量名以从原始键名获取数据的任何其他情况下,这是最简单的方法。

      【讨论】:

        最近更新 更多