JAXB 解组列表

JAXB Unmarshall to List

我正在尝试将此 XML 解组为 Java 对象,一个包含电子邮件地址列表的客户对象。

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

列表有问题,我得到了正确的列表项数 (2),但 emailAddresses 标签的值为 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;
    }
}

单元测试失败

@Test
public void shouldDeserialiseCusomerXMLToObject() throws JAXBException
{
    String xml = "<customer>"
            + "    <emailAddresses>janed@example.com</emailAddresses>"
            + "    <emailAddresses>jdoe@example.org</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( "janed@example.com", msg.getEmailAddresses().get( 0 ).getEmailAddresses() );
}

您的电子邮件地址太多了。

如果您应该将电子邮件地址列表更改为字符串列表,例如

@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;
    }
}

EmailAddressemailAddresses 字段默认被视为子元素,期望 XML 为:

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

由于您的外部 <emailAddresses> 元素不包含内部 <emailAddresses> 元素,因此永远不会分配该字段。

您希望 EmailAddressemailAddresses 字段成为(外部)<emailAddresses> 元素的值,因此您必须告诉 JAXB,通过指定@XmlValue 注释:

@XmlValue
public String getEmailAddresses()
{
    return emailAddresses;
}

@XmlValue 注释在与 @XmlAttribute 结合使用时特别有用,可以像这样支持 XML:

<Person sex="male" age="25">John Doe</Person>

那么 class 将是:

public class Person {
    public enum Sex {
        @XmlEnumValue("male")   MALE,
        @XmlEnumValue("female") FEMALE,
    }
    @XmlAttribute
    private Sex sex;
    @XmlAttribute
    private int age;
    @Value
    private String name;
}