If a class extends a Map and includes some extra fields. E.G a last modified date, Jackson seems to ignore any thing not contained as a property of the map.
I have a class that looks some thing like the following:
import java.io.IOException;
import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.Objects;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Foo extends HashMap<String, String> {
private OffsetDateTime lastModifiedTime;
public Foo() {
super();
lastModifiedTime = OffsetDateTime.now();
}
public void setLastModifiedTime(OffsetDateTime newTime) {
this.lastModifiedTime = newTime;
}
public OffsetDateTime getLastModifiedTime() {
return this.lastModifiedTime;
}
public static void main(String[] args) throws IOException {
Foo f = new Foo();
f.put("hello", "world");
ObjectMapper om = new ObjectMapper();
om.findAndRegisterModules();
String result = om.writeValueAsString(f);
if(f.equals(om.readValue(result, Foo.class))) {
System.out.println("Wooo");
} else {
System.out.println("Booo: " + result);
}
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Foo)) {
return false;
}
if (!super.equals(obj)) {
return false;
}
Foo foo = (Foo) obj;
return Objects.equals(getLastModifiedTime(), foo.getLastModifiedTime());
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), getLastModifiedTime());
}
}
When this runs it outputs booo: {"hello":"world"}
Which does not include the last modified date.
I've tried adding @JsonInclude
annotations to the property and the getters but that doesn't cause it to include the extra field.
What is the correct way to make Jackson include this extra field?
It's generally considered bad practice to extend HashMap. Instead, you should create a class that has a Map, and the additional field.
This will solve your problem, but will also have additional advantages:
By default your map will fall into MapSerializer
. You could register a serializer modifier to add the custom property, but you would be better off nesting the map as a property of Foo
and unwrapping it:
@JsonUnwrapped
private HashMap<String, String> fooMap;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With