【问题标题】:JAXB, my own domain model and suggestionsJAXB,我自己的领域模型和建议
【发布时间】:2012-07-31 17:11:06
【问题描述】:

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

  1. 使用 xmlbeans 从 XSD 生成绑定代码
  2. 编写了许多映射器,从我的域 POJO 填充绑定代码(反之亦然)
  3. 将其编组为 XML
  4. 如果是 Web 服务,我们使用 Axis 1.4 which can use the Serialization/Desrialization factories generated by xmlbeans。这允许我们在两个端点上重用相同的代码:XML over HTTP 和 SOAP/HTTP

现在,我们想开始使用 JAXB,因为它成熟、标准、支持多租户(至少是 Moxy 实现),而且作为 xmlbeans 的一部分已经做的工作​​不多。所以我的问题是

  1. 如何在不生成绑定代码的情况下使用 JAXB。即我不想再编写或维护映射代码(第 2 步)。我想知道我是否可以以某种方式使用 JAXB 直接解组到我的域 POJO?
  2. 如何将它与我的 WebService 集成?我的网络服务使用相同的架构并且不想复制映射。
  3. 还有其他最佳实践建议吗?
  4. 我应该注意哪些问题/经验教训?

【问题讨论】:

  • 我的错。我打算添加 jax-ws
  • 酷,我看到你编辑了标签。希望你能得到解决方案。

标签: jaxb jax-ws cxf


【解决方案1】:

注意:我是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 集成?我的网络服务使用相同的架构并且不想复制映射。

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


3 - 还有其他最佳实践建议吗?

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


更新

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

我知道 Web 服务 API 的一个限制是它们可以工作 反对“由xjc产生的工厂”。在这种情况下,我相信 我不能再使用 XPath 映射。如果我是,请纠正我 错误的。另外,如果我使用注解,我还需要使用 xjc 吗?

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


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

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


另外,如果我采用 XPath 路线,是否会对性能产生影响 或者如果我选择 XML 中的元数据?

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

【讨论】:

  • 2.我知道 Web 服务 API 的一个限制是它们与“xjc 生成的工厂”相悖。在这种情况下,我相信我不能再使用 XPath 映射。如果我错了,请纠正我。另外,如果我使用注解,我还需要使用 xjc 吗?
  • 3.我认为这是使用 XPath 之外的另一种选择,如果我需要支持多租户,这也是唯一的选择。
  • 2.另外,如果我走 XPath 路线或选择 XML 中的元数据,是否会对性能产生影响?
  • @Pangea - 我已根据您的 cmets 更新了我的答案。如果我能提供进一步的帮助,请告诉我。
  • 你能给我 Moxy 的 mvn repo 和 maven 组 id/artifactId。我从没想过发现这会很困难:-(。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-04
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 2012-12-18
相关资源
最近更新 更多