I would like to use a custom serializer for Maps, but only if they are <String, String> maps. I attempted to register a StdSerializer<Map,String, String>>
following the advice in this post like so:
ObjectMapper om = new ObjectMapper();
SimpleModule maskModule = new SimpleModule();
JavaType mapType =
om.getTypeFactory().constructMapLikeType(Map.class, String.class, String.class);
maskModule.addSerializer(new MapSerializer(mapType));
om.registerModule(maskModule);
My Serializer looks as follows:
public static class MapSerializer extends StdSerializer<Map<String, String>> {
MapSerializer(JavaType type) {
super(type);
}
@Override
public void serialize(
Map<String, String> value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
for (Map.Entry<String, String> entry : value.entrySet()) {
gen.writeStringField(entry.getKey(), doOtherStuff(entry.getValue()));
}
gen.writeEndObject();
}
}
This works fine on Map<String, String>
objects, but unfortunately it also gets called for other maps as well. How does one restrict a custom serializer to specific generic types?
CodePudding user response:
Thanks to the comment by @shmosel, I've identified that the following solution appears to allow us to intercept the serializer assignment by using a SerializerModifier
.
public static class MapSerializerModifier extends BeanSerializerModifier {
@Override
public JsonSerializer<?> modifyMapSerializer(SerializationConfig config, MapType valueType, BeanDescription beanDesc, JsonSerializer serializer) {
if(valueType.getKeyType().getRawClass().equals(String.class) &&
valueType.getContentType().getRawClass().equals(String.class)) {
return new MapSerializer();
}
return serializer;
}
}
Then instead of registering the MapSerializer
directly in the module, you register the modifier instead:
SimpleModule maskModule = new SimpleModule();
maskModule.setSerializerModifier(new MapSerializerModifier());
om.registerModule(maskModule);
Now the modifier gets checked for each Map and either returns the custom serializer or the default serializer depending on the object's type properties.