I have a POJO which has a field:
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:
@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.
@JsonProperty can change the visibility of logical property using its access element during serialization and deserialization of JSON. @JsonAlias defines one or more alternative names for a property to be accepted during deserialization.
The @JsonAlias annotation can define one or more alternate names for the attributes accepted during the deserialization, setting the JSON data to a Java object. But when serializing, i.e. getting JSON from a Java object, only the actual logical property name is used instead of the alias.
databind. ObjectMapper ) is the simplest way to parse JSON with Jackson. The Jackson ObjectMapper can parse JSON from a string, stream or file, and create a Java object or object graph representing the parsed JSON. Parsing JSON into Java objects is also referred to as to deserialize Java objects from JSON.
Well, as only deserialization is your concern, @JsonAlias
introduced in 2.9
is perfect for this situation. You can do something like this:
@JsonAlias({"cover_asset", "asset"}) private Asset asset;
@JsonAlias
docs:
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.
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.
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.
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)); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With