jaxb - EclipseLink MOXy 不编码用 @XMLAttribute 注释的子图字段

标签 jaxb eclipselink moxy

问题标题是不言自明的。我可以在此处找到的示例中复制此问题: http://blog.bdoughan.com/2013/03/moxys-object-graphs-inputoutput-partial.html

如果你只是改变

@XmlNamedObjectGraph(
    name="simple",
    attributeNodes={
        @XmlNamedAttributeNode("value"),
    }
)

@XmlNamedObjectGraph(
    name="simple",
    attributeNodes={
        @XmlNamedAttributeNode("type"),
    }
)

然后在 marsahalled 输出中 <phoneNumber>元素为空且没有属性。

我期待看到type作为 <phoneNumber> 的属性元素。

我正在使用 EclipseLink MOXy 版本 2.5.0

输入:

<?xml version="1.0" encoding="UTF-8"?>
<customer id="123">
   <name>Jane Doe</name>
   <billingAddress>
      <street>1 A Street</street>
      <city>Any Town</city>
      <province>Ontario</province>
      <postalCode>A1B 2C3</postalCode>
   </billingAddress>
   <shippingAddress>
      <street>2 B Road</street>
      <city>Another Place</city>
      <province>Quebec</province>
      <postalCode>X7Y 8Z9</postalCode>
   </shippingAddress>
   <phoneNumbers>
      <phoneNumber type="work">555-1111</phoneNumber>
      <phoneNumber type="home">555-2222</phoneNumber>
   </phoneNumbers>
</customer>

输出:

<?xml version="1.0" encoding="UTF-8"?>
<customer id="123">
   <name>Jane Doe</name>
   <billingAddress>
      <city>Any Town</city>
      <province>Ontario</province>
   </billingAddress>
   <phoneNumbers>
      <phoneNumber/>
      <phoneNumber/>
   </phoneNumbers>
</customer>

预期输出:

<?xml version="1.0" encoding="UTF-8"?>
<customer id="123">
   <name>Jane Doe</name>
   <billingAddress>
      <city>Any Town</city>
      <province>Ontario</province>
   </billingAddress>
   <phoneNumbers>
      <phoneNumber type="work" />
      <phoneNumber type="home" />
   </phoneNumbers>
</customer>

类代码(从上面的链接复制粘贴):

客户:

package blog.objectgraphs.metadata;

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

@XmlNamedObjectGraph(
    name="contact info",
    attributeNodes={
        @XmlNamedAttributeNode("name"),
        @XmlNamedAttributeNode(value="billingAddress", subgraph="location"),
        @XmlNamedAttributeNode(value="phoneNumbers", subgraph="simple")
    },
    subgraphs={
        @XmlNamedSubgraph(
            name="location",
            attributeNodes = { 
                @XmlNamedAttributeNode("city"),
                @XmlNamedAttributeNode("province")
            }
        )
    }
)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

    @XmlAttribute
    private int id;

    private String name;

    private Address billingAddress;

    private Address shippingAddress;

    @XmlElementWrapper
    @XmlElement(name="phoneNumber")
    private List<PhoneNumber> phoneNumbers;

}

地址:

package blog.objectgraphs.metadata;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Address {

    private String street;

    private String city;

    private String province;

    private String postalCode;

}

电话号码:

package blog.objectgraphs.metadata;

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

@XmlNamedObjectGraph(
    name="simple",
    attributeNodes={
        @XmlNamedAttributeNode("value"),
    }
)
@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {

    @XmlAttribute
    private String type;

    @XmlValue
    private String value;

}

演示:

package blog.objectgraphs.metadata;

import java.io.File;
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(Customer.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/blog/objectgraphs/metadata/input.xml");
        Customer customer = (Customer) unmarshaller.unmarshal(xml);

        // Output XML
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);

        // Output XML - Based on Object Graph
        marshaller.setProperty(MarshallerProperties.OBJECT_GRAPH, "contact info");
        marshaller.marshal(customer, System.out);

        // Output JSON - Based on Object Graph
        marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
        marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
        marshaller.setProperty(MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true);
        marshaller.marshal(customer, System.out);
    }

}

最佳答案

您看到的问题是由于 EclipseLink 2.5.0 版本中的以下错误造成的:

此问题已在 EclipseLink 2.5.1 版本中修复,可以从以下链接获取:

使用 EclipseLink 2.5.1,您将获得以下输出:

<?xml version="1.0" encoding="UTF-8"?>
<customer>
   <name>Jane Doe</name>
   <billingAddress>
      <city>Any Town</city>
      <province>Ontario</province>
   </billingAddress>
   <phoneNumbers>
      <phoneNumber type="work"/>
      <phoneNumber type="home"/>
   </phoneNumbers>
</customer>

更新

Just 1 difference, earlier it used to marshall phoneNumbers list in JSON as "phoneNumbers" : [ "555-1111", "555-2222" ] but now it marshalls as "phoneNumbers" : [ { "value" : "555-1111" }, { "value" : "555-2222" } ]. The new one is logically more consistent as it represents the true nature of the object graph, however I can think of cases where the old format could be more useful. For example, if you want to send a list of IDs (XMLIDRefs) then sending them as a JSON array of integers looks better than sending a JSON array of objects which in turn contain one integer each

这是我们有目的的改变。大多数用户更喜欢行为一致。现在的方式是,无论是否应用过滤器,您始终可以使用相同的机制来获取值。

如果 POJO 中唯一映射的属性具有 @XmlValue,则不使用 value 键。

关于jaxb - EclipseLink MOXy 不编码用 @XMLAttribute 注释的子图字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26742424/

相关文章:

java - 将外部列添加到 JPA 映射的表会破坏正常运行吗?

java - 使用带内部连接池的 eclipselink 出现网络错误

java - Jersey MOXy 不解析 Snake_case

java - 使用 JAXB 的 XML 中的 header 标记

java - 当同一命名空间的两个 XSD 声明同一元素时,JAXB 如何解决 'is already defined' 错误

wsdl - 从 WSDL 生成基于 JAXB 的 WebService 客户端(Stub)

android - Android 上用于 XML 模式的 JAXB 替代方案?

java - ORA-12899: 列的值太大,即使异常中的值较小

java - 使用 jaxb eclipselink2.2 和 cdata 出现意外结果

java - JAXB/Moxy 将 XmlElements 与 XmlAdapter 结合使用