Sunday, December 18, 2011

JAXB & Collection Properties

In this post will examine the different options JAXB offers for representing collections in XML.  We will look at the following annotations:
  • @XmlElement
  • @XmlElementWrapper
  • @XmlList
  • @XmlList and @XmlAttribute
  • @XmlList and @XmlValue


Java Model

For this example we will use the following model.   We will apply different JAXB annotations to observe the effect it has on the XML representation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.*;
import javax.xml.bind.annotation.*;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
 
    private List<String> emailAddresses;
     
    public Customer() {
        emailAddresses = new ArrayList<String>();
    }
 
    public List<String> getEmailAddresses() {
        return emailAddresses;
    }
 
    public void setEmailAddresses(List<String> emailAddresses) {
        this.emailAddresses = emailAddresses;
    }
 
}

Demo Code

The following code will be used to convert the Customer object to XML.  We will examine the impact of changing the metadata on the XML representation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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(Customer.class);
 
        Customer customer = new Customer();
        customer.getEmailAddresses().add("janed@example.com");
        customer.getEmailAddresses().add("jdoe@example.org");
 
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }
}

Default

By default each item in the collection will be marshalled to an XML element.

1
2
3
4
<customer>
    <emailAddresses>janed@example.com</emailAddresses>
    <emailAddresses>jdoe@example.org</emailAddresses>
</customer>

@XmlElement

We can control the name of the XML element a collection item is marshalled to by using the @XmlElement annotation.

1
2
3
4
5
6
7
8
9
10
11
import java.util.*;
import javax.xml.bind.annotation.*;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
 
    @XmlElement(name="email-address")
    private List<String> emailAddresses;
 
}

The following is the corresponding XML output:

1
2
3
4
<customer>
    <email-address>janed@example.com</email-address>
    <email-address>jdoe@example.org</email-address>
</customer>

@XmlElementWrapper

Sometimes we want to add a grouping element to organize our collection data.  This is done using the @XmlElementWrapper annotation.

1
2
3
4
5
6
7
8
9
10
11
12
import java.util.*;
import javax.xml.bind.annotation.*;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
 
    @XmlElementWrapper(name="email-addresses")
    @XmlElement(name="email-address")
    private List<String> emailAddresses;
 
}

The following is the corresponding XML output:

1
2
3
4
5
6
<customer>
    <email-addresses>
        <email-address>janed@example.com</email-address>
        <email-address>jdoe@example.org</email-address>
    </email-addresses>
</customer>

@XmlList

We can also represent our collection data as space seperated text.  This is done using the @XmlList annotation.

1
2
3
4
5
6
7
8
9
10
11
import java.util.*;
import javax.xml.bind.annotation.*;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
 
    @XmlList
    private List<String> emailAddresses;
 
}

The following is the corresponding XML output:

1
2
3
4
<customer>
    <emailAddresses>janed@example.com jdoe@example.org</emailAddresses>
</customer>
  

@XmlList and @XmlAttribute

Since @XmlList allows us to represent a collection in a single piece of text it is also compatible with an XML attribute.

1
2
3
4
5
6
7
8
9
10
11
12
import java.util.*;
import javax.xml.bind.annotation.*;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
 
    @XmlList
    @XmlAttribute
    private List<String> emailAddresses;
 
}

The following is the corresponding XML output:

1
2
<customer
    emailAddresses="janed@example.com jdoe@example.org"/>

@XmlList and @XmlValue

Since @XmlList allows us to represent a collection in a single piece of text it is also compatible with a single text node.

1
2
3
4
5
6
7
8
9
10
11
12
import java.util.*;
import javax.xml.bind.annotation.*;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
 
    @XmlList
    @XmlValue
    private List<String> emailAddresses;
 
}

The following is the corresponding XML output:

1
<customer>janed@example.com jdoe@example.org</customer>

No comments:

Post a Comment