我有一个POJO,它有一个字段:
public class Media {
private Asset asset;
}
将json响应解析为此资产POJO时,一切都很完美。但是,这个资产带来的关键点略有不同。它可以是:
@JsonProperty("cover_asset")
或
@JsonProperty("asset")
有没有办法注释POJO以识别这种情况并反序列化到同一个字段中。它们不可能出现在同一个响应中。
答案 0 :(得分:50)
好吧,因为只关注反序列化,2.9
中引入的@JsonAlias
非常适合这种情况。你可以这样做:
@JsonAlias({"cover_asset", "asset"})
private Asset asset;
可用于定义一个或多个替代名称的注释 对于一个财产,在反序列化期间被接受作为替代 官方名字。在POJO期间也会公开别名信息 内省,但在主要序列化期间没有影响 名字总是被使用。
注意:如果您使用它们,请确保更新所有相关的依赖项(annotations
,core
,databind
)。仅在没有其他人的情况下更新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;