Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding a Generic Java Class to a JSON using JAXB

Tags:

json

jaxb

jersey

I have the following java class

@XmlRootElement
@XmlSeeAlso(DataClass.class)
public static class EnvelopeClass<T> {

    @XmlElement
    public String version;

    @XmlElement
    public T data;

    EnvelopeClass() {
    }

    EnvelopeClass(String version, T data) {
        this.version = version;
        this.data = data;
    }

}

@XmlRootElement
public static class DataClass {

    @XmlElement
    public String name;

    DataClass() {
    }

    DataClass(String name) {
        this.name = name;
    }

}

I'm creating its instance and marshaling it to json

EnvelopeClass<DataClass> dataClassEnvelopeClass = new EnvelopeClass<DataClass>("1.0", new DataClass("myName"));

I have next result:

{"version":"1.0","data":{"@type":"dataClass","name":"myName"}}

I do not want to have type type information in the json "@type":"dataClass", in other words I want to have next result:

{"version":"1.0","data":{"name":"myName"}}

Exactly this result I have when EnvelopeClass doesn't have Generics.

Is there a way to do this?

like image 444
Vladimir Sorokin Avatar asked Aug 06 '10 09:08

Vladimir Sorokin


People also ask

Can JAXB used for JSON?

JAXB is a java architecture for XML binding is an efficient technology to convert XML to and from Java Object. EclipseLink JAXB (MOXy) is one of JAXB implementation which is mostly used to create java classes from XML or JSON.

What is the name of the tool JAXB used for binding?

JAXB provides the xjc schema compiler tool, the schemagen schema generator tool, and a runtime framework. The xjc schema compiler tool enables you to start with an XML schema definition (XSD) to create a set of JavaBeans that map to the elements and types defined in the XSD schema.

What is JAXB marshalling and Unmarshalling?

JAXB stands for Java Architecture for XML Binding. It provides mechanism to marshal (write) java objects into XML and unmarshal (read) XML into object. Simply, you can say it is used to convert java object into xml and vice-versa.

How does JAXB marshalling work?

In JAXB, marshalling involves parsing an XML content object tree and writing out an XML document that is an accurate representation of the original XML document, and is valid with respect the source schema. JAXB can marshal XML data to XML documents, SAX content handlers, and DOM nodes.


1 Answers

To get the desired behaviour, you can use @XmlAnyElement on the data property instead of @XmlElement. For the @XmlAnyElement property the value will correspond to a class with the matching @XmlRootElement annotation.

EnvelopeClass

import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;

@XmlRootElement 
@XmlSeeAlso(DataClass.class) 
public class EnvelopeClass<T> { 

    @XmlElement 
    public String version; 

    @XmlAnyElement
    public T data; 

    EnvelopeClass() { 
    } 

    EnvelopeClass(String version, T data) { 
        this.version = version; 
        this.data = data; 
    } 

}

DataClass

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="data") 
public class DataClass { 

    @XmlElement 
    public String name; 

    DataClass() { 
    } 

    DataClass(String name) { 
        this.name = name; 
    } 

}

Demo

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(EnvelopeClass.class);

        DataClass data = new DataClass("myName");
        EnvelopeClass envelope = new EnvelopeClass<DataClass>("1.0", data);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(envelope, System.out);
    }
}
like image 111
bdoughan Avatar answered Sep 28 '22 06:09

bdoughan