Jackson jax-rs内容提供程序用于我们基于jax-rs的REST API项目,以处理json和xml内容类型。作为对POJO的响应,我们有映射结构,我们的要求是将此映射结构序列化为XML中的List和JSON格式的Map。(映射键包含空格,因此不可能将这些键转换为XML元素名称)。为了实现这一点,我们实现了一个自定义的XML序列化程序...
JSON:
"properties":{
"a b c":{
"name": "a b c",
"value": "xyz"
}
}
XML:
<property name="a b c" value="xyz"/>
属性地图序列化r:
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上下文解析器配置为解析配置为使用此序列化器的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的一个子类:
public class PropertyMap extends HashMap<String, Property> {
}
响应POJO:
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添加序列化程序,而为其子类us添加序列化程序?因此,我不得不创建标准数据结构的子类来添加自定义序列化程序。
但同时支持使用Map注释添加自定义序列化程序,并且可以正常工作:
@JsonSerialize(using=PropertyMapSerializer.class)
private Map<String, Property> properties = new HashMap<String, Property>();
以这种方式添加序列化程序将使序列化程序同时适用于json和xml格式。不幸的是,我不能这样做,因为这个序列化程序只适用于XML格式。请分享你的想法。
我不知道这是否有帮助,但我发现这对我来说很有效。在序列化程序中,我重写handleType()方法,如下所示:
public class MapToTuple extends JsonSerializer<Map<String, Property>> {
@Override
public void serialize(final Map<String, Property> map, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException {
/*Serializing code here*/
}
@Override
public Class<Map<String, Property>> handledType() {
Class<Map<String, Property>> typeClass = (Class<Map<String, Property>>)(Class<?>)Map.class;
return typeClass;
}
}
然后我像这样注册序列化程序:
SimpleModule mapSerializerModule = new SimpleModule("MapSerializerModule", new Version(1, 0, 0, "beta"));
mapSerializerModule.addSerializer(new MapToTuple());
mapper.registerModule(mapSerializerModule);
希望这有帮助。
你可以试试这样:
@JsonProperty("rowdata")
@JacksonXmlElementWrapper(localName = "ROWDATA")
@JacksonXmlProperty(localName = "ROW")
private List<Row> rows;
Row类是
@JsonSerialize(using = Row.Serializer.class)
public class Row {
private HashMap<String, String> data;
public HashMap<String, String> getData() {
return data;
}
public void setData(HashMap<String, String> data) {
this.data = data;
}
public static class Serializer extends StdSerializer<Row> {
public Serializer() {
this(null);
}
public Serializer(Class<Row> t) {
super(t);
}
@Override
public void serialize(Row row, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (jsonGenerator instanceof ToXmlGenerator) {
final ToXmlGenerator xmlGenerator = (ToXmlGenerator) jsonGenerator;
jsonGenerator.writeStartObject();
for (Map.Entry<String, String> item : row.getData().entrySet()) {
if (item.getValue() == null) {
continue;
}
xmlGenerator.setNextIsAttribute(true);
jsonGenerator.writeFieldName(item.getKey());
jsonGenerator.writeString(item.getValue());
}
jsonGenerator.writeEndObject();
} else {
jsonGenerator.writeStartObject();
for (Map.Entry<String, String> item : row.getData().entrySet()) {
if (item.getValue() == null) {
continue;
}
jsonGenerator.writeFieldName(item.getKey());
jsonGenerator.writeString(item.getValue());
}
jsonGenerator.writeEndObject();
}
}
}
}
它适用于JSON和XML。我的主要目标是将行数据表示为行元素的XML属性。我还希望JSON具有相同的数据结构。下面是它的响应:XML
<ROWDATA>
<ROW F20="0" F14="1" F13="FUBAR"/>
<ROW F20="1" F14="0" F13="FIDO"/>
</ROWDATA>
JSON
"rowdata": [
{
"F20": "0",
"F14": "1",
"F13": "FUBAR"
},
{
"F20": "1",
"F14": "0",
"F13": "FIDO"
}
],