Dear folks I need you advice.
I'm, trying to implement custom Jackson
deserializer for maps but having difficulties with it. As an input data I have the following json:
{
"someMap": {
"one_value": "1",
"another_value: "2"
},
"anotherMap": "{\"100000000\": 360000,\"100000048\": 172800,\"100000036\": 129600,\"100000024\": 86400,\"100000012\": 43200}"
}
As you can see in the second case it has json map inside node value(I'm doing it in that way by intention. Because I want to replace the value from env variable: "anotherMap": "${SOME_MAP:-{\"100000000\": 360000,\"100000048\": 172800,\"100000036\": 129600,\"100000024\": 86400,\"100000012\": 43200}}"
). As I understand I have to differentiate somehow between that 2 maps deserialization flows. So for the first map I need to use default one map deserializer for the second one the custom one to have properly parsed map from the value. At the moment I wrote that code to do that:
// invokation code
new ObjectMapper().registerModule(new ConfigModule()).readValue(is, ConfigModuleTestConfigWrapper.class);
// module code
public class ConfigModule extends SimpleModule {
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.addDeserializers(new Deserializers.Base() {
@Override
public JsonDeserializer<?> findMapDeserializer(MapType type, DeserializationConfig config, BeanDescription beanDesc,
KeyDeserializer keyDeserializer, TypeDeserializer elementTypeDeserializer,
JsonDeserializer<?> elementDeserializer) throws JsonMappingException {
return new MapPropertyDeserializer(type);
}
});
}
private static class MapPropertyDeserializer extends StdScalarDeserializer<Map<String, Integer>> {
MapPropertyDeserializer(MapType type) {
super(type);
}
@Override
public Map<String, Integer> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
JsonNode node = p.readValueAsTree();
if (node == null || node.isContainerNode()) {
// return <default jackson deserializer>
}
System.out.println("isContainerNode ?: " + node.isContainerNode());
System.out.println("isValueNode ?: " + node.isValueNode());
// some parsing flow goes below
JsonNode valueNode = node.get(1);
valueNode.asText();
return new HashMap<>();
}
}
// bean description
@JsonIgnoreProperties
public class ConfigSubstitutorModuleTestConfigWrapper {
private final Map<String, String> someMap;
private final Map<String, Integer> anotherMap;
@JsonCreator
public ConfigSubstitutorModuleTestConfigWrapper(
@JsonProperty("someMap") Map<String, String> someMap,
@JsonProperty("anotherMap") Map<String, Integer> anotherMap
) {
this.someMap = someMap;
this.anotherMap = anotherMap;
}
public Map<String, String> getSomeMap() {
return someMap;
}
public Map<String, Integer> getAnotherMap() {
return anotherMap;
}
}
The problem is(as I understand:)) that I don't know how to return default map deserializer from the deserialize method.
Does anybody have any clue what I could do there to achieve desired goal ?