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?
Advertisement
Answer
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.