JAXB,我自己的域模型和建议

时间:2012-07-31 17:11:07

标签: jaxb jax-ws cxf

我有一个相当大的POJO域模型,自2005年以来逐步建立。我们还在相同的时间框架内逐步开发了XSD。目前,我以下列方式使用xmlbeans来生成通过HTTP发送的xml,并作为WebService响应的一部分。

  1. 使用xmlbeans从XSD生成绑定代码
  2. 编写了很多mappers,用于填充我的域POJO(也是相反的)
  3. 的绑定代码
  4. Marshall it to XML
  5. 包含Web服务,我们使用Axis 1.4 which can use the Serialization/Desrialization factories generated by xmlbeans。这允许我们在两个端点上重用相同的代码:XML over HTTP和SOAP / HTTP
  6. 现在,我们希望开始使用JAXB,因为它是成熟的,标准的,支持多次使用(至少是Moxy实现),而且作为xmlbeans的一部分,还没有做太多的工作。所以我的问题是

    1. 如何在不生成绑定代码的情况下使用JAXB。即我不想再编写或维护映射代码(步骤2)。我想知道我是否能以某种方式使用JAXB直接解组我的域POJO?
    2. 如何将其与我的WebService集成?我的webservice使用相同的模式,并且不想复制映射。
    3. 还有其他最佳做法建议吗?
    4. 我应该知道的任何问题/经验教训?

1 个答案:

答案 0 :(得分:2)

注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。

  

1 - 如何在不生成绑定代码的情况下使用JAXB。即我没有   想要编写或维护映射代码(步骤2)了。我是   想知道我是否可以某种方式使用JAXB解组我的域POJO   直接?

使用自己的域对象的关键是基于路径的映射。如果没有这个,绑定框架使用的模型必须与XML文档非常相似。下面是我想提供的示例,其中一个简单的地址对象被映射到Google Geocoding API V2的结果。

package blog.geocode;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement(name="kml")
@XmlType(propOrder={"country", "state", "city", "street", "postalCode"})
public class Address {

    @XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:SubAdministrativeArea/ns:Locality/ns:Thoroughfare/ns:ThoroughfareName/text()")
    private String street;

    @XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:SubAdministrativeArea/ns:Locality/ns:LocalityName/text()")
    private String city;

    @XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:AdministrativeAreaName/text()")
    private String state;

    @XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:CountryNameCode/text()")
    private String country;

    @XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:SubAdministrativeArea/ns:Locality/ns:PostalCode/ns:PostalCodeNumber/text()")
    private String postalCode;

}

下面是一个示例的链接,其中相同的对象模型映射到Google和Yahoo天气服务:


  

2 - 如何将其与我的WebService集成?我的webservice使用相同的模式,并且不想复制映射。

如果Axis支持多个JAXB提供程序,那么您应该能够在没有太多配置的情况下利用MOXy。可能只需在与您的域模型相同的包中添加jaxb.properties文件。


  

3 - 还有其他最佳做法建议吗?

如果您想避免将任何编译时依赖项添加到域模型中,那么您可能需要考虑将元数据表示为XML。


<强>更新

以下是您通过评论提出的问题的答案:

  

我对webservice API的一个限制是它们有效   反对“xjc生成的工厂”。在这种情况下我相信   我不能再使用XPath映射。如果我是,请纠正我   错误。另外,如果我使用注释,我还需要使用xjc吗?

我不确定CXF,但标准的JAX-WS实现允许您从您自己的域模型开始,或通过XJC生成一个。下面是几个在Java对象开始时在JAX-WS环境中使用MOXy的示例:


  

我认为除了使用XPath之外,这是另一种选择,也是   如果我需要支持多租户,这是唯一的选择。

外部映射文档不是XPath的替代方法,它只是指定元数据的另一种方式。有些人更喜欢这种方法,如果他们不想在类上引入任何MOXy依赖项,那么这些类将仅用于对象到XML或对象到JSON的转换。对于多租户,我经常注释所有共享属性,然后每个租户都有一个映射文档来映射扩展。


  

此外,如果我使用XPath路由,是否有任何性能影响   或者如果我选择XML格式的元数据?

使用基于路径的映射没有任何性能影响。初始化JAXBContext时,这一切都会得到优化。当引导外部绑定文档时,JAXBContext创建稍微慢一些,因为正在完成更多的工作,但由于JAXB / MOXy是异常配置,因此这些文档往往很小。对使用外部映射文档的Marshaller / Unmarshaller没有影响。