Pretty printing XML with Jackson library
Asked Answered
E

3

23

I am trying to use Jackson library to serialize Java objects into XML by using JAXB annotations. However, I face an issue in pretty-printing the XML output.

Here is my sample code usage:

ObjectMapper mapper = new XmlMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
String xml = mapper.writeValueAsString(person);

And, I'm seeing the below exception. The issue here is Jackson uses Stax2Writer as XML writer and Stax2 doesn't seem to support writing raw strings (in this case DefaultPrettyPrinter tries to write "\n" as raw string).

    com.fasterxml.jackson.databind.JsonMappingException: Not implemented (through reference chain: xml.serialization.jackson.dto.Person["name"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:232)
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:197)
    at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:187)
    at com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializer.serializeFields(XmlBeanSerializer.java:174)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider.serializeValue(XmlSerializerProvider.java:92)
    at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2818)
    at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:2275)
    at xml.serialization.jackson.SerializationTest.main(SerializationTest.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.UnsupportedOperationException: Not implemented
    at org.codehaus.stax2.ri.Stax2WriterAdapter.writeRaw(Stax2WriterAdapter.java:380)
    at org.codehaus.stax2.ri.Stax2WriterAdapter.writeRaw(Stax2WriterAdapter.java:373)
    at com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter$Lf2SpacesIndenter.writeIndentation(DefaultXmlPrettyPrinter.java:498)
    at com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter.writeLeafElement(DefaultXmlPrettyPrinter.java:271)
    at com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.writeString(ToXmlGenerator.java:489)
    at com.fasterxml.jackson.databind.ser.std.StringSerializer.serialize(StringSerializer.java:39)
    at com.fasterxml.jackson.databind.ser.std.StringSerializer.serialize(StringSerializer.java:21)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializer.serializeFields(XmlBeanSerializer.java:161)
    ... 10 more

Any thoughts on how to work it around?

Esperanto answered 9/4, 2014 at 0:11 Comment(0)
I
33

According to the Stax2WriterAdapter's documentation thier default implementation is incomplete. Also comments in the code say that the writeRaw() method cannot be implemented using Stax 1.0 which is default for Java runtime.

You should switch to use a Stax2 library as suggested on this wiki page.

After I added the following Maven dependency to my project, the example below started to work as expected:

<dependency>
    <groupId>org.codehaus.woodstox</groupId>
    <artifactId>woodstox-core-asl</artifactId>
    <version>4.1.4</version>
</dependency>

Code example:

public class JacksonXmlMapper {
    public static class Person {
        final public String name;

        public Person(String name) {
            this.name = name;
        }
    }

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new XmlMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        System.out.println(mapper.writeValueAsString(new Person("John")));
    }
}

Output:

<Person>
   <name>John</name>
</Person>
Ishtar answered 17/4, 2014 at 21:10 Comment(0)
D
-1

I have used the below dependencies to sort the above said problem. Here is the list of those:

1) jackson-annotations-2.9.8.jar

2) jackson-core-2.9.8.jar

3) jackson-databind-2.9.8.jar

4) jackson-dataformat-xml-2.9.8.jar

5) jackson-module-jaxb-annotations-2.9.8.jar

6) stax2-api-4.0.0.jar

7) woodstox-core-asl-4.4.1.jar

enter image description here

@Urosh T: content updated.

Decagon answered 1/1, 2019 at 17:59 Comment(1)
Please don't give a '1 link answer'. Use links to provide reference to your solution. In this case in particular, a link to an image is not very helpful. Please consider editing your answerRustproof
I
-4

Its caused because of the java.lang.UnsupportedOperationException:

if you implement the unimplemented method, your code should be working fine. for futher insights about the exception, please check this

("java.lang.UnsupportedOperationException: Not supported yet.").

Thanks!!

Innutrition answered 10/4, 2014 at 7:20 Comment(1)
I have already mentioned that Stax2Writer doesn't seem to support writing raw characters like "\n". My question is more about how to pretty print XML with jackson since they document that it's supported.Esperanto

© 2022 - 2024 — McMap. All rights reserved.