1

I have a rather large object tree which I want to export to XML. An object named Person is used at several places (as userCreated, userModified of many child entities, as client, etc)

Depending of the use of the Person-object I need to have different elements in the xml. Example:

<policy>
  <userCreated>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
  </userCreated>
  <client>
    <clientId>1234</clientId>
    <email>jdoe@example.com</email>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
  </client>
</policy>

userCreated and client are instances of the same object (named Person)

How can this be set up in bindings.xml ?

4

1 回答 1

0

You can use EclipseLink JAXB (MOXy)'s @XmlNamedObjectGraph extension to support this use case. What @XmlNamedObjectGraph allows you to do is create multiple views on your data.

Person

Below we will use @XmlNamedObjectGraph to create a view on the Person class that only exposes 2 fields (firstName and lastName).

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;

@XmlNamedObjectGraph(
    name = "simple", 
    attributeNodes = {
        @XmlNamedAttributeNode("firstName"), 
        @XmlNamedAttributeNode("lastName")
     }
)
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

    private int clientId;
    private String firstName;
    private String lastName;
    private String email;

    public void setClientId(int clientId) {
        this.clientId = clientId;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

Policy

We will also use @XmlNamedObjectGraph on the Policy class. It says that for the userCreated field apply the named object graph called simple that we defined on the Person class.

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlNamedObjectGraph(
    name = "policy", 
    attributeNodes = {
        @XmlNamedAttributeNode(value = "userCreated", subgraph = "simple"),
        @XmlNamedAttributeNode("client") 
    }
)
public class Policy {

    private Person userCreated;
    private Person client;

    public void setUserCreated(Person userCreated) {
        this.userCreated = userCreated;
    }

    public void setClient(Person client) {
        this.client = client;
    }

}

Demo

In the demo code below we will specify the named object graph that we want applied on the Marshaller using the MarshallerProperties.OBJECT_GRAPH property.

import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.MarshallerProperties;

public class Demo {

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

        Person person = new Person();
        person.setClientId(1234);
        person.setFirstName("John");
        person.setLastName("Doe");
        person.setEmail("jdoe@example.com");

        Policy policy = new Policy();
        policy.setClient(person);
        policy.setUserCreated(person);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(MarshallerProperties.OBJECT_GRAPH, "policy");
        marshaller.marshal(policy, System.out);
    }

}

Output

Below is the output from running the demo code:

<?xml version="1.0" encoding="UTF-8"?>
<policy>
   <userCreated>
      <firstName>John</firstName>
      <lastName>Doe</lastName>
   </userCreated>
   <client>
      <clientId>1234</clientId>
      <firstName>John</firstName>
      <lastName>Doe</lastName>
      <email>jdoe@example.com</email>
   </client>
</policy>

For More Information

于 2013-06-18T15:17:59.097 回答