Jackson @JsonAnyGetter and @JsonAnySetter Example

By Arvind Rai, 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.

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;
    }
    ------
} 
Suppose we have data in a 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"); 
Now serialize the Address class using ObjectMapper and print it.
ObjectMapper mapper = new ObjectMapper();
String jsonData = mapper.writerWithDefaultPrettyPrinter()
   .writeValueAsString(address);
System.out.println(jsonData); 
We will get JSON output as given below.
{
  "country" : "India",
  "district" : "Varanasi",
  "state" : "Uttar Pradesh",
  "village" : "ABCD"
} 
To make "any getter" method inactive, use 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);
    }
    ------
} 
Find the sample code to use @JsonAnySetter at property level.
public class Address {
    @JsonAnySetter
    private Map<String, String> addressDetails = new HashMap<>();
    ------
} 
Suppose we have JSON data as following.
String jsonData =   "{"
		+"\"village\" : \"ABCD\","
		+"\"district\" : \"Varanasi\","
     	        +"\"state\" : \"Uttar Pradesh\","
 	        +"\"country\" : \"India\""
		+"}"; 
Now we will deserialize JSON data using 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));
} 
Find the output.
country: India
district: Varanasi
state: Uttar Pradesh
village: ABCD 
To make "any setter" method inactive, use 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.gradle
apply 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'
} 
Address.java
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);
    }    
} 
JSONToObject.java
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));
		}
         }
} 
Output
country: India
district: Varanasi
state: Uttar Pradesh
village: ABCD 
ObjectToJSON.java
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);
  }
} 
Output
{
  "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;
	}
} 
JSONToObject.java
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());
        }
} 
Output
country: India
state: Uttar Pradesh
District: Varanasi
Village: ABCD 

References

Annotation Type JsonAnyGetter
Annotation Type JsonAnySetter
POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us