Reputation: 2437
I am trying to unmarshall this XML to Java objects, a Customer object containing a List of EmailAdresses.
<customer>
<emailAddresses>[email protected]</emailAddresses>
<emailAddresses>[email protected]</emailAddresses>
</customer>
Having an issue with the list, I get the correct number of list items (2), but the value of the emailAddresses tag is null
Customer.java
@XmlRootElement( name = "customer" )
public class Customer
{
private List<EmailAddress> emailAddresses;
public Customer()
{
emailAddresses = new ArrayList<EmailAddress>();
}
public List<EmailAddress> getEmailAddresses()
{
return emailAddresses;
}
public void setEmailAddresses( List<EmailAddress> emailAddresses )
{
this.emailAddresses = emailAddresses;
}
}
EmailAddress.java
public class EmailAddress
{
private String emailAddresses;
public String getEmailAddresses()
{
return emailAddresses;
}
public void setEmailAddresses( String emailAddresses )
{
this.emailAddresses = emailAddresses;
}
}
Failing Unit Test
@Test
public void shouldDeserialiseCusomerXMLToObject() throws JAXBException
{
String xml = "<customer>"
+ " <emailAddresses>[email protected]</emailAddresses>"
+ " <emailAddresses>[email protected]</emailAddresses>"
+ "</customer>";
JAXBContext jaxbContext = JAXBContext.newInstance( Customer.class );
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader( xml );
Customer msg = ( Customer ) jaxbUnmarshaller.unmarshal( reader );
// This passes, I have 2 emailAddresses
assertEquals( 2, msg.getEmailAddresses().size() );
// This fails, I have a null pointer instead of the email address
assertEquals( "[email protected]", msg.getEmailAddresses().get( 0 ).getEmailAddresses() );
}
Upvotes: 0
Views: 95
Reputation: 159086
The emailAddresses
field of EmailAddress
is by default treated as a subelement, expecting the XML to be:
<customer>
<emailAddresses>
<emailAddresses>[email protected]</emailAddresses>
</emailAddresses>
<emailAddresses>
<emailAddresses>[email protected]</emailAddresses>
</emailAddresses>
</customer>
Since your outer <emailAddresses>
element doesn't contain an inner <emailAddresses>
element, the field is never assigned.
You want the emailAddresses
field of EmailAddress
to be the value of the (outer) <emailAddresses>
element, so you have to tell JAXB
that, by specifying the @XmlValue
annotation:
@XmlValue
public String getEmailAddresses()
{
return emailAddresses;
}
The @XmlValue
annotation is especially useful when combined with @XmlAttribute
, to support XML like this:
<Person sex="male" age="25">John Doe</Person>
Where class would then be:
public class Person {
public enum Sex {
@XmlEnumValue("male") MALE,
@XmlEnumValue("female") FEMALE,
}
@XmlAttribute
private Sex sex;
@XmlAttribute
private int age;
@Value
private String name;
}
Upvotes: 3
Reputation: 1380
You have a level too many of email addresses.
If you should change the list of email addresses to a list of strings, like
@XmlRootElement( name = "customer" )
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;
}
}
Upvotes: 0