Note that there are some explanatory texts on larger screens.

plurals
  1. POContextualDeserializer for mapping JSON to different types of maps with Jackson
    primarykey
    data
    text
    <p>This JSON snippet should be mapped to a Java-Objects that contains a <code>cars</code> field of type <code>Map&lt;String, Car&gt;</code> and a <code>bikes</code> field of type <code>Map&lt;String, Bike&gt;</code>. Because bikes and cars can be empty strings in the JSON file, i need a custom deserializer (<a href="https://stackoverflow.com/questions/6684358/map-a-json-field-that-can-have-different-types-with-jackson">See this question</a>).</p> <pre><code>{ "id" : "1234", "name" : "John Doe", "cars" : { "Tesla Model S" : { "color" : "silver", "buying_date" : "2012-06-01" }, "Toyota Yaris" : { "color" : "blue", "buying_date" : "2005-01-01" } }, "bikes" : { "Bike 1" : { "color" : "black" }, "Bike 2" : { "color" : "red" } } } </code></pre> <p>I thought about having instances of a generic custom deserializer that can be returned by the <code>createContextual(DeserializationConfig cfg, BeanProperty property)</code> method of a <code>ContextualDeserializer</code> based on the BeanProperty parameter. The generic custom deserializer looks like this:</p> <pre><code>public class MapsGenericDeserializer&lt;T&gt; extends JsonDeserializer&lt;Map&lt;String, T&gt;&gt; { private ObjectMapper mapper; // ObjectMapper without special map deserializer public MapsGenericDeserializer(ObjectMapper mapper) { this.mapper = mapper; } @Override public Map&lt;String, T&gt; deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { ObjectCodec codec = jp.getCodec(); JsonNode node = codec.readTree(jp); if (!"".equals(node.getTextValue())) { return mapper.readValue(node, new TypeReference&lt;Map&lt;String, T&gt;&gt;() {}); } return null; // Node was an empty string } } </code></pre> <p>The contextual serializer below does not work because casting from <code>MapsGenericDeserializer&lt;Car&gt;</code> to <code>JsonDeserializer&lt;Map&lt;String,?&gt;&gt;</code> is not possible. Maybe this is possible in newer Versions of Java, but it does not work on the Version of Android I am coding for. So how can I implement the desired behaviour?</p> <pre><code>public class MapsDeserializer extends JsonDeserializer&lt;Map&lt;String, ?&gt;&gt; implements ContextualDeserializer&lt;Map&lt;String, ?&gt;&gt; { private ObjectMapper mapper; MapsGenericDeserializer&lt;Car&gt; carDeserializer = new MapsGenericDeserializer&lt;Car&gt;(mapper); MapsGenericDeserializer&lt;Bike&gt; bikeDeserializer = new MapsGenericDeserializer&lt;Bike&gt;(mapper); public MapsDeserializer(ObjectMapper mapper) { this.mapper = mapper; } @Override public JsonDeserializer&lt;Map&lt;String, ?&gt;&gt; createContextual(DeserializationConfig cfg, BeanProperty property) throws JsonMappingException { Class&lt;?&gt; targetClass = property.getType().containedType(1).getRawClass(); if(targetClass.equals(Car.class) { return carDeserializer; // Type mismatch! } else if (targetClass.equals(Bike.class)) { return bikeDeserializer; // Type mismatch! } else { return this; } } // ... } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload