How must I bind (bidirectional) the following json snippet to the Java objects below with Jackson?
I want the key/value pairs of the Json newsletter node to end up in the Map of the newsletter field. What must be the Jackson config (annotations and others) to bind this ? Sorry, I don't know how :( (using the latest version of Jackson).
The Json format below is fixed, I receive it from a third party rest service (I can't change it). I can change the java code, but prefer the setup below.
JSON:
{
"newsletter": {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
}
The Java Objects:
class Preferences {
private NewsLetter newsLetter;
// getter/setter for field newsLetter.
}
class NewsLettter {
private Map<String, String> properties;
// getter/setter for field properties.
}
You could simply use @JsonAnySetter
for deserialization
Marker annotation that can be used to define a non-static, two-argument method (first argument name of property, second value to set), to be used as a "fallback" handler for all otherwise unrecognized properties found from JSON content.
And @JsonAnyGetter
for serialization.
Marker annotation that can be used to define a non-static, no-argument method or member field as something of a reverse of
JsonAnySetter
method; basically being used like a getter but such that contents of the returned Map (type must beMap
) are serialized as if they were actual properties of the bean that contains method/field with this annotations
public class Newsletter {
private final Map<String, String> properties = new HashMap<>();
@JsonAnySetter
public void addProperty(String name, String value) {
properties.put(name, value);
}
@JsonAnyGetter
public Map<String, String> getProperties() {
return properties;
}
}
This should work just fine for your use case.
Test
public class Main {
public static void main(String[] args) throws Exception {
String json
= "{\n"
+ " \"newsletter\": {\n"
+ " \"key1\": \"value1\",\n"
+ " \"key2\": \"value2\",\n"
+ " \"key3\": \"value3\"\n"
+ " }\n"
+ "}";
ObjectMapper mapper = new ObjectMapper();
Preferences prefs = mapper.readValue(json, Preferences.class);
Map<String, String> properties = prefs.getNewsletter().getProperties();
for (Map.Entry<String, String> prop: properties.entrySet()) {
System.out.println(prop.getKey() + ":" + prop.getValue());
}
}
}
See Also: