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格式。请分享你的想法。
你可以试试这样:
@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"
}
],
我不知道这是否有帮助,但我发现这对我来说很有效。在序列化程序中,我重写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);
希望这有帮助。
我目前正在尝试使用Jackson2.8.4将自定义映射类型序列化和反序列化为JSON。我已经设法基于这个答案实现了序列化,但我正在与反序列化作斗争。下面是一个例子:
我有一个类,它通过实现中的和方法来实现自定义Kryo序列化程序(请参见下面的示例)。如何用Spark注册此自定义序列化程序? 现在在Spark: 不幸的是,Spark没有给我注册自定义序列化程序的选项。你知道有没有办法做到这一点?
我试图创建会影响序列化值的自定义jackson注释。 意思是: 现在序列化对象X(10)将导致: 我怎样才能做到这一点?
问题内容: 我正在尝试创建将影响序列化值的自定义杰克逊注释。 含义: 现在序列化对象X(10)将导致: 我该如何实现? 问题答案: 结果:
情况如下:我已经设法让Jackson反序列化以下通用 作为HTTP客户端,并使用exchange
下面的代码再现了这个问题: 上面的代码不做其他注册“自定义”序列化程序的事情(只是委托回原始序列化程序),但它生成的JSON没有null属性: {“第一个”:“鲍勃”,“最后一个”:“巴克”} 我读过许多看似相关的SO文章,但没有一篇能让我找到解决方案。我尝试在序列化时显式地将映射器设置为,但没有成功。 我唯一的线索是JavaDoc for JsonSerializer中的一条注释: 注意:永远不