Jackson序列化:将字段值设置为XML元素名称 [英] Jackson Serialization: Setting field value as XML element name
问题描述
我们正在使用Jackson jax-rs XML内容提供程序来处理基于jax-rs的REST API项目中的XML内容类型。
在序列化POJO列表时,我们需要从POJO中的字段动态设置xml元素名称。
We are using Jackson jax-rs XML content providers for handling XML content type in our jax-rs based REST API project. In the serializing a List of POJOs, we need to set the xml element name dynamically from a field in the POJO.
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
}
默认Jackson序列化XML:
Default Jackson serialized 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>
我们的要求,即将类型设置为XML元素名称。
Our requirement, ie., set type as the XML element name.
<ResponsePOJO>
<Error>
<msg>Some random error message</msg>
</Error>
<Warning>
<msg>Some random warning message</msg>
</Warning>
</ResponsePOJO>
为了实现这一目标,我们以下列方式编写了一个自定义XML序列化程序:
In order to achieve this, we wrote a custom XML serializer in the following manner:
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);
}
}
}
并使用注释添加了序列化程序:
And added the serializer using annotation:
@JacksonXmlProperty
@JacksonXmlElementWrapper(useWrapping = false)
@JsonSerialize(using=MessageListSerializer.class)
private List<Message> message = new ArrayList<Message>();
但是在使用Jackson XMLMapper序列化ResponsePOJO时,我们得到以下异常......
But while serializing the ResponsePOJO using Jackson XMLMapper, we are getting the following exception...
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
你能否帮我解决这个问题...
Could you please help me resolve this issue...
推荐答案
编辑上一个解决方案:
你几乎就在那里,只需要将 @JsonIgnore
添加到私有字符串类型; //错误或警告
Edit to previous solution:
You're nearly there, just need to add @JsonIgnore
to private String type; // "Error" or "Warning"
<ResponsePOJO>
<Error>
<msg>error message</msg>
</Error>
<Warning>
<msg>warning message</msg>
</Warning>
</ResponsePOJO>
以下将输出上述xml:
The following will output the above xml:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Main demo = new Main();
demo.run();
}
public void run(){
ObjectMapper xmlMapper = new XmlMapper();
ResponsePOJO responsePOJO = new ResponsePOJO();
Message message = new Message();
message.setType("Error");
message.setMsg("error message");
Message message2 = new Message();
message2.setType("Warning");
message2.setMsg("warning message");
responsePOJO.getMessage().add(message);
responsePOJO.getMessage().add(message2);
try {
String xml = xmlMapper.writeValueAsString(responsePOJO);
System.out.println(xml);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
public class ResponsePOJO {
@JacksonXmlProperty
@JacksonXmlElementWrapper(useWrapping = false)
@JsonSerialize(using=MessageListSerializer.class)
private List<Message> message = new ArrayList<Message>();
public List<Message> getMessage() {
return message;
}
}
public class Message {
@JsonIgnore
private String type; // "Error" or "Warning"
private String msg; // The actual message
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
}
与班级一起
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.util.List;
/**
* Created by Pand on 08/04/2015.
*/
public class MessageListSerializer extends
JsonSerializer<List<Main.Message>> {
@Override
public void serialize(List<Main.Message> value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
for(Main.Message me : value){
jgen.writeObjectField(me.getType(), me);
}
}
}
with dependencies
with dependencies
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>woodstox-core-asl</artifactId>
<version>4.1.4</version>
</dependency>
</dependencies>
这篇关于Jackson序列化:将字段值设置为XML元素名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!