Here is an example of java class. I need all the fields to be immutable after deserialization.
It can be done if I set the field type to ImmutableMap
explicitly. But can I instruct Jackson to deserialize it into an ImmutableMap
neither changing the field type Map
nor add annotation like @JsonDeserialize
?
public class AdCategoryConfigImmute {
private ImmutableMap<String, List<Integer>> sceneMap; // type is immutable explicitly
private Map<String, List<Integer>> trMap;
}
CodePudding user response:
In order to specify the subtype for a particular field needs to be deserialized, you can make use of the @JsonDeserialize
annotation. Required type needs to be provided through its as
property.
public class AdCategoryConfigImmute {
@JsonDeserialize(as = ImmutableMap.class)
private Map<String, List<Integer>> sceneMap;
// getter, setters
}
But since here we need an ImmutableMap
(or its subtype) from Guava library, you need to register Jackson's GuavaModule
(link to the Maven repository), otherwise deserialization would fail.
Example:
public static void main(String[] args) throws IOException {
String json = """
{
"sceneMap" : {
"foo" : [1, 2, 3]
}
}
""";
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new GuavaModule());
AdCategoryConfigImmute pojo = mapper.readValue(json, AdCategoryConfigImmute.class);
System.out.println(pojo.getSceneMap().getClass());
}
Output:
class com.google.common.collect.SingletonImmutableBiMap
Note: if you're using Spring Boot, it would register the GuavaModule for you while configuring ObjectMapper
at the application start up (no need to register the module it manually, you only need to add a dependency).