Jackson序列化:将字段值设置为XML元素名称

din*_*p24 5 java xml jax-rs jackson

我们使用Jackson jax-rs XML内容提供程序在我们基于jax-rs的REST API项目中处理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
}
Run Code Online (Sandbox Code Playgroud)

默认Jackson序列化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>
Run Code Online (Sandbox Code Playgroud)

我们的要求,即将类型设置为XML元素名称.

<ResponsePOJO>
    <Error>
        <msg>Some random error message</msg>
    </Error>
    <Warning>
        <msg>Some random warning message</msg>
    </Warning>
</ResponsePOJO>
Run Code Online (Sandbox Code Playgroud)

为了实现这一点,我们以下列方式编写了一个自定义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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并使用注释添加了序列化程序:

@JacksonXmlProperty
@JacksonXmlElementWrapper(useWrapping = false)
@JsonSerialize(using=MessageListSerializer.class)
private List<Message> message = new ArrayList<Message>();
Run Code Online (Sandbox Code Playgroud)

但是在使用Jackson XMLMapper序列化ResponsePOJO时,我们得到以下异常......

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
Run Code Online (Sandbox Code Playgroud)

你能帮我解决这个问题吗?

ABO*_*BOS 0

我的意见是你的方法过于复杂。我会将您的消息类重组为:

public class Message { private String msg; // The actual message },并根据类型对其进行子类化:

public class Error extends Message { }

public class Warning extends Message { }

此外,这种方法允许您为每种类型添加自定义字段,更加灵活。