JSON Jackson将不同的密钥解析到同一个字段中

时间:2013-10-24 11:30:49

标签: java json jackson

我有一个POJO,它有一个字段:

public class Media {
 private Asset asset;
}

将json响应解析为此资产POJO时,一切都很完美。但是,这个资产带来的关键点略有不同。它可以是:

  @JsonProperty("cover_asset")

  @JsonProperty("asset")

有没有办法注释POJO以识别这种情况并反序列化到同一个字段中。它们不可能出现在同一个响应中。

4 个答案:

答案 0 :(得分:50)

好吧,因为只关注反序列化,2.9中引入的@JsonAlias非常适合这种情况。你可以这样做:

@JsonAlias({"cover_asset", "asset"})
private Asset asset;

@JsonAlias docs

  

可用于定义一个或多个替代名称的注释   对于一个财产,在反序列化期间被接受作为替代   官方名字。在POJO期间也会公开别名信息   内省,但在主要序列化期间没有影响   名字总是被使用。

注意:如果您使用它们,请确保更新所有相关的依赖项(annotationscoredatabind)。仅在没有其他人的情况下更新annotations会让我失去运行时错误。

答案 1 :(得分:46)

更简洁一点,我建议为此使用两个单独的@JsonSetter注释。这是一个有效的例子。这意味着您的java类只有一个getter方法用于属性而不是两个。您还可以使您不希望向Media私有客户端公开的setter以特殊方式处理其中一个json密钥。

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.databind.ObjectMapper;

@SuppressWarnings("unused")
public class Media {

    private Asset asset;

    @JsonGetter("asset")
    public Asset getAsset() {
        return asset;
    }

    @JsonSetter("asset")
    public void setAsset(Asset asset) {
        this.asset = asset;
    }

    @JsonSetter("cover_asset")
    private void setMediaAsset(Asset asset) {
        if (this.asset == null) {
            setAsset(asset);
        }
    }


    private static class Asset {
        @JsonProperty("foo")
        private String foo;
    }

    public static void main(String[] args) throws Exception {
        String withAsset = "{'asset': {'foo':'bar'}}";
        String withCoverAsset = "{'cover_asset': {'foo':'bar'}}";

        ObjectMapper mapper = new ObjectMapper();
        Media mediaFromAsset = mapper.readValue(withAsset.replace('\'','"'), Media.class);
        Media mediaFromCoverAsset = mapper.readValue(withCoverAsset.replace('\'','"'), Media.class);

        System.out.println(mediaFromAsset.asset.foo.equals(mediaFromCoverAsset.asset.foo));

    }
}

答案 2 :(得分:6)

我建议对两个属性名称使用getter / setter,它们指的是相同的POJO字段。

public class Media {
    private Asset asset;

    @JsonProperty("cover_asset")
    public Asset getCoverAsset() {
      return asset;
    }

    public void setCoverAsset(Asset asset) {
      this.asset= asset;
    }

    @JsonProperty("asset")
    public Asset getAsset() {
      return asset;
    }

    public void setAsset(Asset asset) {
      this.asset= asset;
    }
}

另见我对可能重复问题的回答: Different names of JSON property during serialization and deserialization

答案 3 :(得分:1)

Vikas与JsonAlias的很好回答。

只需添加一下,您还可以从这两个世界(JsonProperty&Alias)中受益(自jackson 2.9起):

@JsonProperty("cover_asset")    
@JsonAlias({"asset", "cover_asset","amazing_asset"})
private Asset asset; 

Reference.