Поставщики контента Jackson jax-rs используются в нашем проекте REST API, основанном на jax-rs, для обработки типа содержимого json и xml. В ответ POJO у нас есть структура карты, и наше требование состоит в том, чтобы сериализовать эту структуру карты как Список в XML и как карту в формате JSON. (Ключи карты содержат пробелы и, следовательно, невозможно преобразовать эти ключи в имена XML-элементов). Для достижения этой цели мы внедрили пользовательский сериализатор для XML ...Jackson: Регистрация пользовательского XML-сериализатора для структуры данных карты
JSON:
"properties":{
"a b c":{
"name": "a b c",
"value": "xyz"
}
}
XML:
<property name="a b c" value="xyz"/>
PropertyMapSerializer:
public class PropertyMapSerializer extends
JsonSerializer<Map<String, Property>> {
@Override
public void serialize(Map<String, Property> value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
provider.defaultSerializeValue(value.values(), jgen);
}
}
JAX-RS context resolver настроен для разрешения экземпляра XMLMapper, настроенного для использования этого сериализатора.
@Provider
@Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML })
public class XmlMapperContextResolver implements ContextResolver<XmlMapper> {
private final XmlMapper xmlMapper = new XmlMapper();
@Override
public XmlMapper getContext(Class<?> type) {
return xmlMapper;
}
public XmlMapperContextResolver() {
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);
//Compilation error while adding Serializer for Map and HashMap class.
//Error: The method addSerializer(Class<? extends T>, JsonSerializer<T>) in the type SimpleModule is not applicable for the arguments (Class<Map>, PropertyMapSerializer)
//module.addSerializer(HashMap.class, new PropertyMapSerializer());
//module.addSerializer(Map.class, new PropertyMapSerializer());
//This works
module.addSerializer(PropertyMap.class, new PropertyMapSerializer());
xmlMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
xmlMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
xmlMapper.registerModule(module);
}
}
Где PropertyMap подкласс HashMap: POJO
public class PropertyMap extends HashMap<String, Property> {
}
Ответа:
public class ResponsePOJO {
//Commenting out as serializer couldn't be added for HashMap
//private Map<String, Property> properties = new HashMap<String, Property>();
private Map<String, Property> properties = new PropertyMap();
}
Не мог бы вы, пожалуйста, дайте мне знать, почему я не может добавить сериализатора для HashMap при добавлении Сериализатор для поддержки нашего подкласса? Из-за этого я вынужден создавать подклассы стандартных структур данных для добавления пользовательских сериализаторов.
Но в то же время добавления пользовательского сериализатора с помощью аннотаций к карте поддерживается и она работает:
@JsonSerialize(using=PropertyMapSerializer.class)
private Map<String, Property> properties = new HashMap<String, Property>();
Добавление сериалайзера таким образом сделает сериализатор применим как для JSON и XML-формата. К сожалению, я не могу этого сделать, поскольку этот сериализатор применим только для формата XML. Пожалуйста, поделитесь своими мыслями.