If there are multiple custom XML Serializers (XMLStreamWriter
) in a class, serialization fails.
I have two classes: CustomClass1
, CustomClass2
. There is a wrapping class TestJacksonXml1
. When I am trying to serialize TestJacksonXml1
, it throws an exception.
CustomClass1
class CustomClass1 {
int prop1;
public CustomClass1(int prop1) {
this.prop1 = prop1;
}
public int getProp1() {
return prop1;
}
static class CustomClass1Serializer extends StdSerializer<CustomClass1> {
public CustomClass1Serializer() { this(null); }
public CustomClass1Serializer(Class<CustomClass1> t) {
super(t);
}
@Override
public void serialize(CustomClass1 customClass1, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
final ToXmlGenerator toXmlGenerator = (ToXmlGenerator) jsonGenerator;
final XMLStreamWriter staxWriter = (toXmlGenerator).getStaxWriter();
try {
staxWriter.writeStartElement("class1");
staxWriter.writeCharacters(String.valueOf(customClass1.prop1));
staxWriter.writeEndElement();
} catch (XMLStreamException e){
e.printStackTrace();
}
}
}
}
CustomClass2
class CustomClass2 {
int prop2;
public CustomClass2(int prop2) {
this.prop2 = prop2;
}
public int getProp2() {
return prop2;
}
static class CustomClass2Serializer extends StdSerializer<CustomClass2> {
public CustomClass2Serializer() { this(null); }
public CustomClass2Serializer(Class<CustomClass2> t) {
super(t);
}
@Override
public void serialize(CustomClass2 customClass2, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
final ToXmlGenerator toXmlGenerator = (ToXmlGenerator) jsonGenerator;
final XMLStreamWriter staxWriter = (toXmlGenerator).getStaxWriter();
try {
staxWriter.writeStartElement("class2");
staxWriter.writeCharacters(String.valueOf(customClass2.prop2));
staxWriter.writeEndElement();
} catch (XMLStreamException e){
e.printStackTrace();
}
}
}
}
Enclosing Class
public class TestJacksonXml1 {
@JsonSerialize(using = CustomClass1.CustomClass1Serializer.class)
CustomClass1 obj1;
@JsonSerialize(using = CustomClass2.CustomClass2Serializer.class)
CustomClass2 obj2;
public TestJacksonXml1(CustomClass1 obj1, CustomClass2 obj2) {
this.obj1 = obj1;
this.obj2 = obj2;
}
public CustomClass1 getObj1() {
return obj1;
}
public CustomClass2 getObj2() {
return obj2;
}
public static void main(String[] args) throws JsonProcessingException {
XmlMapper xmlMapper = new XmlMapper();
System.out.println(xmlMapper.writeValueAsString(new TestJacksonXml1(new CustomClass1(10), new CustomClass2(20))));
}
}
The exception I get is
Exception in thread "main" com.fasterxml.jackson.core.JsonGenerationException: Can not write a field name, expecting a value
at com.fasterxml.jackson.core.JsonGenerator._reportError(JsonGenerator.java:1961)
at com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.writeFieldName(ToXmlGenerator.java:435)
at com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.writeFieldName(ToXmlGenerator.java:577)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:725)
at com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializerBase.serializeFields(XmlBeanSerializerBase.java:202)
at com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializer.serialize(XmlBeanSerializer.java:117)
at com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider.serializeValue(XmlSerializerProvider.java:107)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3905)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3219)
at fk.reportsvc.common.TestJacksonXml1.main(TestJacksonXml1.java:39)
When I comment out one of the custom serializers, the other one works. Why is it so?
Shouldn't we use two/multiple custom serializers (with XMLStreamWriter
) at once?
If I use JsonGenerator
directly instead of XMLStreamWriter
, then I am able to use both custom serializers at once.
PS: My actual business classes contain many fields that are to be converted into nested XML elements and attributes. Hence preferring XMLStreamWriter
directly over others.