@JsonAnyGetter Jackson Annotation

@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.

References: https://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonAnyGetter.html

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 [email protected]

Other Jackson Annotations –

Liked the article? Share this on

Leave a Comment

Your email address will not be published.