Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
762 views
in Technique[技术] by (71.8m points)

java - Jaxb marshalling with custom annotations

I have a requirement, to marshall/unmarshall some elements of java pojo depending upon a custom annotation marked on the field. suppose there are 3 fields in my java pojp

@CustomVersion("v1")
private String field1;
@CustomVersion("v1","v2")
private String field2;
@CustomVersion("v2")
private String field3;

i would like to marshall only the fields with v1 if i pass version="v1" parameter while conversion in jaxb. if i pass v2, all fields with v2 annotation should only be marshalled.

is that even possible using jaxb? i am sure selective marshalling would be supported through some library or way, am not still able to figure it out after quite some searching. any help or advice or pointers are highly appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

Below is an example of how you could use MOXy's @XmlNamedObjectGraphs extension to map your use case.

Java Model

Foo

The @XmlNamedObjectGraphs extension allows you to specify multiple subsets of mappings identified by a key.

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.oxm.annotations.XmlNamedAttributeNode;
import org.eclipse.persistence.oxm.annotations.XmlNamedObjectGraph;
import org.eclipse.persistence.oxm.annotations.XmlNamedObjectGraphs;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlNamedObjectGraphs({
    @XmlNamedObjectGraph(
        name="v1",
        attributeNodes = { 
            @XmlNamedAttributeNode("field1"),
            @XmlNamedAttributeNode("field2")}),
    @XmlNamedObjectGraph(
        name="v2",
        attributeNodes = { 
            @XmlNamedAttributeNode("field2"),
            @XmlNamedAttributeNode("field3")})
})
public class Foo {

    private String field1 = "ONE";
    private String field2 = "TWO";
    private String field3 = "THREE";

}

jaxb.properties

To use MOXy as your JAXB provider you need to include a file called jaxb.properties with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html).

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Demo Code

Demo

You can specify the key corresponding to the object graph to have that subset applied to the object you are marshalling.

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import org.eclipse.persistence.jaxb.MarshallerProperties;

public class Demo {

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

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        Foo foo = new Foo();

        // Marshal Everything
        marshaller.marshal(foo, System.out);

        // Marshal "v1" Data
        marshaller.setProperty(MarshallerProperties.OBJECT_GRAPH, "v1");
        marshaller.marshal(foo, System.out);

        // Marshal "v2" Data
        marshaller.setProperty(MarshallerProperties.OBJECT_GRAPH, "v2");
        marshaller.marshal(foo, System.out);
    }

}

Output

<?xml version="1.0" encoding="UTF-8"?>
<foo>
   <field1>ONE</field1>
   <field2>TWO</field2>
   <field3>THREE</field3>
</foo>
<?xml version="1.0" encoding="UTF-8"?>
<foo>
   <field1>ONE</field1>
   <field2>TWO</field2>
</foo>
<?xml version="1.0" encoding="UTF-8"?>
<foo>
   <field2>TWO</field2>
   <field3>THREE</field3>
</foo>

For More Information


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...