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

2022-08-31 13:25:48

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

public class Media {
 private Asset asset;
}

将 json 响应解析到此资产 POJO 中时,一切都会完美地工作。但是,与此资产附带的密钥略有不同。它可以是:

  @JsonProperty("cover_asset")

  @JsonProperty("asset")

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


答案 1

好吧,由于只有反序列化是您关注的问题,因此引入@JsonAlias非常适合这种情况。你可以做这样的事情:2.9

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

@JsonAlias文档

可用于定义属性的一个或多个备用名称的批注,在反序列化期间被接受为正式名称的替代名称。别名信息在 POJO 自检期间也会公开,但在始终使用主名称的序列化期间没有影响。

注意:如果您正在使用所有相关依赖项(,请确保更新它们。,只是在没有其他人的情况下更新给我带来了运行时错误。annotationscoredatabindannotations


答案 2

更简洁地说,我建议为此使用两个单独的@JsonSetter注释。下面是一个工作示例。这意味着您的 java 类将只有一个 getter 方法用于该属性,而不是两个。您还可以将不希望的 setter 公开给 Media 的客户端,并以特殊方式处理其中一个 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));

    }
}