3
votes

I have to use a lib that only gives me a JAXBContext to marshall and unmarshall XML data to Java objects. Also I don't ever see XML: Only the JAXB objects are passed to me. What I now need is a conversion of those objects not to XML, but to JSON.

Is there a way to create a marshaller from the given JAXBContext that can be used to generate JSON output?

The situation is that I'm not only transforming data. I also have logic that acts on the Java objects between XML and JSON (and manipulates the data). Also it's a two-way transformation. The JAXBContext is the information I have about the transformation between XML and Java objects - My intention was to reuse this context information for not having to implement a second transformation with a second technology different to JAXB. The JAXBContext (and its Java objects) already have the information about the XML structure; The automated recognition of that structure by JAXB is the time-saving reason for using it.

1
How try with transforming first XML and then to Json like XML to Json ??? Or may need to implement suitable xml parser to transform xml content to requried Json format !! - Wundwin Born
The problem is that I'm not only transforming data. I also have logic that have to act on the Java objects between XML and JSON. Also it's a two-way transformation. The JAXBContext is the information I have about the transformation between XML and Java objects - My intention was to reuse that context information to not having to implement a second transformation with a second technology different to JAXB. The JAXBContext (and its Java objects) already have the information about the XML structure; The automated recognition of that structure by JAXB is the time-saving reason for using it. - Sebastian Barth
Also I don't ever see XML. Only the JAXB objects are passed to me. (Added this to the question) - Sebastian Barth

1 Answers

1
votes

If your JAXB classes just use the basic annotations, you can take a look at JacksonJAXBAnnotations, allows Jackson mapper to recognize JAXN annotations. Four lines of code (in the simplest marshalling case) would be all you would need.

ObjectMapper mapper = new ObjectMapper();
JaxbAnnotationModule module = new JaxbAnnotationModule();
mapper.registerModule(module);
mapper.writeValue(System.out, yourJaxbObject);

You can see the link above for all the supported annotations. The maven artifact you'll need is

<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-jaxb-annotations</artifactId>
    <version>2.4.0</version>
</dependency>
  • See the github for jackson-module-jaxb-annotations - Note this artifact has dependencies on jackson-core and jackson-databind. So if you're not using maven, then you will need to make sure to download these artifacts also

Simple Exmaple:

JAXB Class

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "hello",
    "world"
})
@XmlRootElement(name = "root")
public class Root {

    @XmlElement(required = true)
    protected String hello;
    @XmlElement(required = true)
    protected String world;

    // Getters and Setters
}

XML

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <hello>JAXB</hello>
    <world>Jackson</world>
</root>

Test

public class TestJaxbJackson {
    public static void main(String[] args) throws Exception {
        JAXBContext context = JAXBContext.newInstance(Root.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        InputStream is = TestJaxbJackson.class.getResourceAsStream("test.xml");
        Root root = (Root)unmarshaller.unmarshal(is);
        System.out.println(root.getHello() + " " + root.getWorld());

        ObjectMapper mapper = new ObjectMapper();
        JaxbAnnotationModule module = new JaxbAnnotationModule();
        mapper.registerModule(module);
        mapper.writeValue(System.out, root);
    }
}

Result

{"hello":"JAXB","world":"Jackson"}

Update

Also see this post. It looks like MOXy also offers this support.