Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserialization of map with integer keys using Jackson

I have to serialize a simple integer-to-string map as JSON and then read it back. The serialization is pretty simple, however since JSON keys must be strings the resulting JSON looks like:

{
  "123" : "hello",
  "456" : "bye",
}

When I read it using code like:

new ObjectMapper().readValue(json, Map.class)

I get Map<String, String> instead of Map<Integer, String> that I need.

I tried to add key deserializer as following:

    Map<Integer, String> map1 = new HashMap<>();
    map1.put(1, "foo");
    map1.put(2, "bar");


    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    module.addKeyDeserializer(Integer.class, new KeyDeserializer() {
        @Override
        public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            System.out.println("deserialize " + key);
            return Integer.parseInt(key);
        }
    });

    mapper.registerModule(module);
    String json = mapper.writeValueAsString(map1);


    Map map2 = mapper.readValue(json, Map.class);
    System.out.println(map2);
    System.out.println(map2.keySet().iterator().next().getClass());

Unfortunately my key deserialzier is never called and map2 is in fact Map<String, String>, so my example prints:

{1=foo, 2=bar}
class java.lang.String

What am I doing wrong and how to fix the problem?

like image 232
AlexR Avatar asked Jul 05 '15 13:07

AlexR


People also ask

What is Jackson deserialization?

Deserialization annotations are used when we deserialize JSON string into an Object. Jackson library provides several deserialization annotations such as @JsonCreator, @JacksonInject, @JsonAnySetter, etc. These annotations are mostly used in setter.

How does Jackson deserialize dates from JSON?

This is how i'm deserializing the date: SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); getObjectMapper(). getDeserializationConfig(). setDateFormat(dateFormat);

Does Jackson use Java serialization?

This short tutorial shows how the Jackson library can be used to serialize Java object to XML and deserialize them back to objects.

What does Jackson ObjectMapper do?

The Jackson ObjectMapper can parse JSON from a string, stream or file, and create a Java object or object graph representing the parsed JSON. Parsing JSON into Java objects is also referred to as to deserialize Java objects from JSON. The Jackson ObjectMapper can also create JSON from Java objects.


1 Answers

Use

Map<Integer, String> map2 = 
        mapper.readValue(json, new TypeReference<Map<Integer, String>>(){});

or

    Map<Integer, String> map2 = 
        mapper.readValue(json, TypeFactory.defaultInstance()
                         .constructMapType(HashMap.class, Integer.class, String.class));

Your program will output below text:

deserialize 1
deserialize 2
{1=foo, 2=bar}
class java.lang.Integer
like image 52
Wand Maker Avatar answered Oct 14 '22 05:10

Wand Maker