Java JSON Jackson 将不同的键解析为同一字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19564711/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JSON Hymanson parse different keys into same field
提问by DArkO
I have a POJO which has a field:
我有一个 POJO,它有一个字段:
public class Media {
private Asset asset;
}
Everything works perfectly when parsing a json response into this asset POJO. but however there is a slight difference with the key this asset comes with. It can either be:
将 json 响应解析为此资产 POJO 时,一切正常。但是,此资产附带的密钥略有不同。它可以是:
@JsonProperty("cover_asset")
or
或者
@JsonProperty("asset")
Is there a way to annotate the POJO to recognize this case and de-serialize into the same field. Its not possible for both of them to appear in the same response.
有没有办法注释 POJO 以识别这种情况并将其反序列化为同一字段。它们不可能出现在同一个响应中。
采纳答案by Vikas Prasad
Well, as only deserialization is your concern, @JsonAlias
introduced in 2.9
is perfect for this situation. You can do something like this:
好吧,由于您只关心反序列化,因此@JsonAlias
引入 in2.9
非常适合这种情况。你可以这样做:
@JsonAlias({"cover_asset", "asset"})
private Asset asset;
Annotation that can be used to define one or more alternative names for a property, accepted during deserialization as alternative to the official name. Alias information is also exposed during POJO introspection, but has no effect during serialization where primary name is always used.
可用于为属性定义一个或多个替代名称的注释,在反序列化期间接受作为正式名称的替代。别名信息也在 POJO 内省期间公开,但在始终使用主名称的序列化期间没有影响。
Note: Make sure you update all related dependencies(annotations
, core
, databind
) if you are using them. Updating just annotations
without others threw me runtime error.
注意:如果您正在使用它们,请确保更新所有相关的依赖项 ( annotations
, core
, databind
)。在annotations
没有其他人的情况下更新会引发运行时错误。
回答by DRCB
I'd propose to use getters/setters, for both property names, which are referring to the same POJO field.
我建议对引用相同 POJO 字段的两个属性名称使用 getter/setter。
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;
}
}
See also my answer to possible duplicate question: Different names of JSON property during serialization and deserialization
另请参阅我对可能重复问题的回答: 序列化和反序列化期间 JSON 属性的不同名称
回答by whaley
More succinctly, I would suggest using two separate @JsonSetter annotations for this. Here's a working example. This means that your java class will only have one getter method to use for the property instead of two. You can also make the setter you don't want exposed to clients of Media private and treat one of the json keys in a special manner.
更简洁地说,我建议为此使用两个单独的 @JsonSetter 注释。这是一个工作示例。这意味着您的 java 类将只有一个 getter 方法用于属性而不是两个。您还可以将不想暴露给 Media 客户端的 setter 设为私有,并以特殊方式处理其中一个 json 键。
import com.fasterxml.Hymanson.annotation.JsonGetter;
import com.fasterxml.Hymanson.annotation.JsonProperty;
import com.fasterxml.Hymanson.annotation.JsonSetter;
import com.fasterxml.Hymanson.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));
}
}
回答by Robocide
Great answer By Vikas with JsonAlias.
Vikas 和 JsonAlias 的出色回答。
Just adding that you can also benefit from both of the worlds (JsonProperty&Alias) [Since Hymanson 2.9]:
只需补充一点,您还可以从这两个世界中受益(JsonProperty&Alias)[自 Hymanson 2.9]:
@JsonProperty("cover_asset")
@JsonAlias({"asset", "cover_asset","amazing_asset"})
private Asset asset;