java Jackson序列化:将字段值设置为XML元素名称
在基于jax-rs的restapi项目中,我们使用jacksonjax-rsxml内容提供者来处理XML内容类型。 在序列化POJO列表时,我们需要从POJO中的字段动态设置xml元素名称
public class ResponsePOJO {
@JacksonXmlProperty
@JacksonXmlElementWrapper(useWrapping = false)
private List<Message> message = new ArrayList<Message>();
}
public class Message {
private String type; // "Error" or "Warning"
private String msg; // The actual message
}
默认序列化XML:
<ResponsePOJO>
<message>
<type>Error</type>
<msg>Some random error message</msg>
</message>
<message>
<type>Warning</type>
<msg>Some random warning message</msg>
</message>
</ResponsePOJO>
我们的需求是,将type设置为XML元素名
<ResponsePOJO>
<Error>
<msg>Some random error message</msg>
</Error>
<Warning>
<msg>Some random warning message</msg>
</Warning>
</ResponsePOJO>
为了实现这一点,我们以以下方式编写了自定义XML序列化程序:
public class MessageListSerializer extends
JsonSerializer<List<Message>> {
@Override
public void serialize(List<Message> value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
for(Message me : value){
jgen.writeObjectField(me.getType(), me);
}
}
}
并使用注释添加了序列化程序:
@JacksonXmlProperty
@JacksonXmlElementWrapper(useWrapping = false)
@JsonSerialize(using=MessageListSerializer.class)
private List<Message> message = new ArrayList<Message>();
但是在使用Jackson XMLMapper序列化ResponseJo时,我们得到了以下异常
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Array index out of range: -2
at com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider.serializeValue(XmlSerializerProvider.java:100)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2866)
at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:2289)
Caused by: java.lang.ArrayIndexOutOfBoundsException: Array index out of range: -2
at com.ctc.wstx.sw.BufferingXmlWriter.writeRaw(BufferingXmlWriter.java:241)
at com.ctc.wstx.sw.BaseStreamWriter.writeRaw(BaseStreamWriter.java:1113)
at com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.writeRaw(ToXmlGenerator.java:592)
at com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter$Lf2SpacesIndenter.writeIndentation(DefaultXmlPrettyPrinter.java:517)
at com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter.writeEndObject(DefaultXmlPrettyPrinter.java:223)
at com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.writeEndObject(ToXmlGenerator.java:422)
at com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializer.serialize(XmlBeanSerializer.java:119)
at com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider.serializeValue(XmlSerializerProvider.java:92)
... 3 more
你能帮我解决这个问题吗
# 1 楼答案
我的意见是你的方法太复杂了。我将改为将您的消息类重组为:
public class Message { private String msg; // The actual message }
,并根据类型对其进行子类化:public class Error extends Message { }
public class Warning extends Message { }
此外,这种方法允许您向每种类型添加自定义字段,这更灵活
# 2 楼答案
“我无法在评论中发布,因为它太长了” 以下是自定义类:
我用我的演示代码测试了它:
它返回:
不过,您需要调整元素名称以获得所需的结果
# 3 楼答案
我也有类似的问题。我编写了一个自定义JsonSerializer,为集合中的每个项生成不同的xml元素名(从@JsonTypeName读取)
这是我的JsonSerializer:
对于以下POJO(由lombok生成的getter和构造函数):
和测试代码:
这是输出:
PS:我用jackson版本2.9.3测试我的代码
# 4 楼答案
编辑到上一个解决方案: 您就快到了,只需要将
@JsonIgnore
添加到private String type; // "Error" or "Warning"
以下内容将输出上述xml:
随班
有依赖关系