Master Dynamic JSON Fields in Java with @JsonAnyGetter & @JsonAnySetter

This article explains how to handle JSON objects with unknown or changing fields in Java by using Jackson's @JsonAnySetter to collect them during deserialization and @JsonAnyGetter to serialize them back, complete with code examples, pitfalls, and a concise analogy.

macrozheng
macrozheng
macrozheng
Master Dynamic JSON Fields in Java with @JsonAnyGetter & @JsonAnySetter

@JsonAnySetter: Collecting Unknown JSON Fields

When deserializing JSON, fields that are not declared in the Java class can be captured by a method annotated with @JsonAnySetter. Jackson calls this method for each unknown property, passing the property name and value, which you can store in a Map<String, Object>.

@JsonAnySetter
public void addAdditionalProperty(String key, Object value) {
    this.additionalProperties.put(key, value);
}

Example:

import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;

public class Person {
    private String name;
    private int age;
    private Map<String, Object> additionalProperties = new HashMap<>();

    @JsonAnySetter
    public void addAdditionalProperty(String key, Object value) {
        this.additionalProperties.put(key, value);
    }

    public Map<String, Object> getAdditionalProperties() {
        return additionalProperties;
    }

    // getters and setters omitted
}

public class Main {
    public static void main(String[] args) throws Exception {
        String json = "{\"name\":\"John\",\"age\":30,\"address\":\"123 Street\",\"nickname\":\"Johnny\"}";
        ObjectMapper mapper = new ObjectMapper();
        Person person = mapper.readValue(json, Person.class);
        System.out.println("Name: " + person.name);
        System.out.println("Age: " + person.age);
        System.out.println("Additional Properties: " + person.getAdditionalProperties());
    }
}

Running the program prints:

Name: John
Age: 30
Additional Properties: {address=123 Street, nickname=Johnny}

@JsonAnyGetter: Serializing Dynamic Properties

To include the stored dynamic fields when converting a Java object back to JSON, annotate a getter that returns the map with @JsonAnyGetter. Jackson will flatten the map entries into the resulting JSON object.

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
    return additionalProperties;
}

Continuing the previous example, serializing the Person instance yields:

{"name":"John","age":30,"address":"123 Street","nickname":"Johnny"}

Summary

Annotation

Analogy

Purpose @JsonAnySetter Universal drawer that accepts any customer request

JSON → Java: collect unknown fields @JsonAnyGetter Display shelf that shows stored items

Java → JSON: output extra fields as normal properties

This technique is ideal for JSON structures with non‑fixed fields such as configuration items, parameter lists, or plugin metadata.

JavaserializationJSONjacksonDeserializationDynamicProperties
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.