@JsonAnyGetter annotation allows key/value pairs of the map to be used as JSON standard properties. This annotation can be applied to a non-static method that does not accept any argument and return a map of key-value pair. These key-value pairs are serialized as JSON properties along with standard fields.
Few points about @JsonAnyGetter annotation –
- This annotation is valid only in the case of serialization. If you want to achieve similar functionality for deserialization as well, then @JsonAnySetter will do the trick for you
- @JsonAnyGetter works quite well for the additional fields we might want to put into our JSON. We can add the extra fields to a map, and they will be serialized and shown in the resulting JSON
- @JsonAnyGetter will work only with the map instances
- It cannot be placed on the top of a member variable. This annotation should be placed on a non-static getter method which doesn’t accept any arguments
@JsonAnyGetter
private Map<String, Object> values;
public Map<String, Object> getValues() {
return values;
}
public void setValues(Map<String, Object> values) {
this.values = values;
}
This is wrong
private Map<String, Object> values;
@JsonAnyGetter
public Map<String, Object> getValues() {
return values;
}
public void setValues(Map<String, Object> values) {
this.values = values;
}
This is correct
private Map<String, Object> values;
public Map<String, Object> getValues() {
return values;
}
@JsonAnyGetter
public void setValues(Map<String, Object> values) {
this.values = values;
}
This won’t give any error, but it won’t work as we want it to
private Map<String, Object> values;
@JsonAnyGetter
public Map<String, Object> getValues(int value) {
return values;
}
public void setValues(Map<String, Object> values) {
this.values = values;
}
This also won’t give any error and won’t work either
Let’s look at the resulting JSON with and without using the @JsonAnyGetter annotation. In that way, we will be able to visualize the difference between the two.
Without Using the @JsonAnyGetter annotation
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Person {
private String firstName;
private String lastName;
private Map<String, Object> values;
public Person() {
super();
}
public Person(String firstName, String lastName, Map<String, Object> values) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.values = values;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Map<String, Object> getValues() {
return values;
}
public void setValues(Map<String, Object> values) {
this.values = values;
}
public static void main(String[] args) throws JsonProcessingException {
Person person = new Person();
person.setFirstName("Codekru");
person.setLastName("Programming");
Map<String, Object> values = new HashMap<>();
values.put("age", 20);
values.put("profession", "blogging");
person.setValues(values);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person)); // serializing object
}
}
Output –
{
"firstName" : "Codekru",
"lastName" : "Programming",
"values" : {
"profession" : "blogging",
"age" : 20
}
}
Using the @JsonAnyGetter annotation now
Now, we have used @JsonAnyGetter annotation at the getter method of the values map.
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Person {
private String firstName;
private String lastName;
private Map<String, Object> values;
public Person() {
super();
}
public Person(String firstName, String lastName, Map<String, Object> values) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.values = values;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@JsonAnyGetter
public Map<String, Object> getValues() {
return values;
}
public void setValues(Map<String, Object> values) {
this.values = values;
}
public static void main(String[] args) throws JsonProcessingException {
Person person = new Person();
person.setFirstName("Codekru");
person.setLastName("Programming");
Map<String, Object> values = new HashMap<>();
values.put("age", 20);
values.put("profession", "blogging");
person.setValues(values);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person)); // serializing object
}
}
Output –
{
"firstName" : "Codekru",
"lastName" : "Programming",
"profession" : "blogging",
"age" : 20
}
age and profession have been serialized as standard properties like firstName and lastName.
There is one counterpart annotation of this @JsonAnySetter. We will discuss it in our next post.
We hope that you have liked the article. If you have any doubts or concerns, please feel free to write us in the comments or mail us at admin@codekru.com.
Other Jackson Annotations –