Jackson @JsonAnyGetter and @JsonAnySetter
March 13, 2018
On this page we will provide Jackson @JsonAnyGetter
and @JsonAnySetter
example. @JsonAnyGetter
is annotated at non-static, no-argument method to serialize a Java Map
into JSON. The return type of this method must be of Map
type. @JsonAnySetter
is annotated at non-static two-argument method or at object property of Map
type. In the two-argument method, first one is for key and second one is for value. @JsonAnySetter
can work as fallback during deserialization of JSON. It means if logical properties are available for some JSON fields and not for all then @JsonAnySetter
will deserialize the rest of the JSON fields in Map
. Now let us discuss @JsonAnyGetter
and @JsonAnySetter
annotations step by step.
Contents
Technologies Used
Find the technologies being used in our example.1. Java 9
2. Jackson 2.9.4
3. Gradle 4.3.1
4. Eclipse Oxygen
@JsonAnyGetter
1.@JsonAnyGetter
defines non-static and no-argument method as "any getter". It behaves as an accessor for getting a set of key-value pairs. Method name can be anything as we want.
2. The method annotated with
@JsonAnyGetter
must return a Java Map
.
3.
@JsonAnyGetter
has an element enabled
that accepts Boolean values. When we pass false
to enabled
element, the annotation @JsonAnyGetter
becomes inactive for that method annotated with it.
4.
@JsonAnyGetter
should be used at only one property.
5. The method annotated with
@JsonAnyGetter
will serialize Map
into JSON. The key of Map
will be the name of JSON field and the corresponding value for that key of Map
will be the value of corresponding JSON field.
A method is annotated with
@JsonAnyGetter
as following.
public class Address { private Map<String, String> addressDetails = new HashMap<>(); @JsonAnyGetter public Map<String, String> getAddress() { return addressDetails; } ------ }
Map
as following.
Address address = new Address(); Map<String, String> addressDetails = address.getAddress(); addressDetails.put("village", "ABCD"); addressDetails.put("district", "Varanasi"); addressDetails.put("state", "Uttar Pradesh"); addressDetails.put("country", "India");
Address
class using ObjectMapper
and print it.
ObjectMapper mapper = new ObjectMapper(); String jsonData = mapper.writerWithDefaultPrettyPrinter() .writeValueAsString(address); System.out.println(jsonData);
{ "country" : "India", "district" : "Varanasi", "state" : "Uttar Pradesh", "village" : "ABCD" }
enabled
element of @JsonAnyGetter
annotation as given below.
@JsonAnyGetter(enabled = false) public Map<String, String> getAddress() { return addressDetails; }
@JsonAnySetter
1.@JsonAnySetter
defines a logical "any setter" mutator. The method annotated with @JsonAnySetter
should be non-static and with two-arguments. First argument will be to set JSON field name and second will be to set corresponding value. Method name can be anything as we want.
2.
@JsonAnySetter
can also be annotated on object property of Map
type.
3.
@JsonAnySetter
has an element enabled
that accepts Boolean values. When we pass false
to enabled
element, the annotation @JsonAnySetter
becomes inactive for that method or object property annotated with it.
4. If there are logical properties to set values from JSON then only those JSON fields will be set by
@JsonAnySetter
for which there are no logical properties. It means @JsonAnySetter
can be used as fallback in JSON deserialization.
Find the sample code to use
@JsonAnySetter
at method level.
public class Address { private Map<String, String> addressDetails = new HashMap<>(); @JsonAnySetter public void setAddress(String name, String value) { this.addressDetails.put(name, value); } ------ }
@JsonAnySetter
at property level.
public class Address { @JsonAnySetter private Map<String, String> addressDetails = new HashMap<>(); ------ }
String jsonData = "{" +"\"village\" : \"ABCD\"," +"\"district\" : \"Varanasi\"," +"\"state\" : \"Uttar Pradesh\"," +"\"country\" : \"India\"" +"}";
ObjectMapper
as following.
ObjectMapper mapper = new ObjectMapper(); Address address = mapper.readValue(jsonData, Address.class); Map<String, String> details = address.getAddress(); for(String key: details.keySet()) { System.out.println(key+": "+ details.get(key)); }
country: India district: Varanasi state: Uttar Pradesh village: ABCD
enabled
element of @JsonAnySetter
annotation as given below.
@JsonAnySetter(enabled = false) public void setAddress(String name, String value) { this.addressDetails.put(name, value); }
Example-1: @JsonAnyGetter and @JsonAnySetter
build.gradleapply plugin: 'java' apply plugin: 'eclipse' archivesBaseName = 'concretepage' version = '1' repositories { mavenCentral() } dependencies { compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.4' compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.4' compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.4' }
package com.concretepage; import java.util.HashMap; import java.util.Map; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; public class Address { private Map<String, String> addressDetails = new HashMap<>(); @JsonAnyGetter public Map<String, String> getAddress() { return addressDetails; } @JsonAnySetter public void setAddress(String name, String value) { this.addressDetails.put(name, value); } }
package com.concretepage; import java.io.IOException; import java.util.Map; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; public class JSONToObject { public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException { String jsonData = "{" +"\"village\" : \"ABCD\"," +"\"district\" : \"Varanasi\"," +"\"state\" : \"Uttar Pradesh\"," +"\"country\" : \"India\"" +"}"; ObjectMapper mapper = new ObjectMapper(); Address address = mapper.readValue(jsonData, Address.class); Map<String, String> details = address.getAddress(); for(String key: details.keySet()) { System.out.println(key+": "+ details.get(key)); } } }
country: India district: Varanasi state: Uttar Pradesh village: ABCD
package com.concretepage; import java.util.Map; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public class ObjectToJSON { public static void main(String[] args) throws JsonProcessingException { Address address = new Address(); Map<String, String> addressDetails = address.getAddress(); addressDetails.put("village", "ABCD"); addressDetails.put("district", "Varanasi"); addressDetails.put("state", "Uttar Pradesh"); addressDetails.put("country", "India"); ObjectMapper mapper = new ObjectMapper(); String jsonData = mapper.writerWithDefaultPrettyPrinter() .writeValueAsString(address); System.out.println(jsonData); } }
{ "country" : "India", "district" : "Varanasi", "state" : "Uttar Pradesh", "village" : "ABCD" }
Example-2: @JsonAnySetter as Fallback
We will provide example here to use@JsonAnySetter
as fallback. We will create logical properties for some JSON fields and not for all. We will deserialize other JSON fields using @JsonAnySetter
.
Address.java
package com.concretepage; import java.util.HashMap; import java.util.Map; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; public class Address { @JsonProperty("village") private String myVillage; @JsonProperty("district") private String myDistrict; @JsonAnySetter private Map<String, String> addressDetails = new HashMap<>(); public String getMyVillage() { return myVillage; } public void setMyVillage(String myVillage) { this.myVillage = myVillage; } public String getMyDistrict() { return myDistrict; } public void setMyDistrict(String myDistrict) { this.myDistrict = myDistrict; } public Map<String, String> getAddressDetails() { return addressDetails; } }
package com.concretepage; import java.io.IOException; import java.util.Map; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; public class JSONToObject { public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException { String jsonData = "{" +"\"village\" : \"ABCD\"," +"\"district\" : \"Varanasi\"," +"\"state\" : \"Uttar Pradesh\"," +"\"country\" : \"India\"" +"}"; ObjectMapper mapper = new ObjectMapper(); Address address = mapper.readValue(jsonData, Address.class); Map<String, String> details = address.getAddressDetails(); for(String key: details.keySet()) { System.out.println(key+": "+ details.get(key)); } System.out.println("District: "+ address.getMyDistrict()); System.out.println("Village: "+ address.getMyVillage()); } }
country: India state: Uttar Pradesh District: Varanasi Village: ABCD
References
Annotation Type JsonAnyGetterAnnotation Type JsonAnySetter