Home > Blockchain >  How to set Jackson's deserialization strategy for Collections to obtain a collection of an Immu
How to set Jackson's deserialization strategy for Collections to obtain a collection of an Immu

Time:12-26

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

  • Related