0

我遇到了JAXB / Spring Web Services的问题。下面是详细说明。我很感激任何可以帮助我解决它的建议。如果需要,我可以提供更多详细信息。

我正在编写一个返回某些实体列表的 Web 服务。Spring WS 是契约优先的框架,所以我从 XSD 开始,类似于:

<element name="GetEntitiesRequest" type="Something"/>
<element name="GetEntitiesResponse" type="Entities"/>

<complexType name="Entities">
    <sequence>
        <element name="Entity" type="Entity" minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
</complexType>

<complexType name="Entity">
    <sequence>
        (...)
    </sequence>
</complexType>

它运作良好。但是,“实体”类型开始增长(有很多元素),这导致了性能问题(响应中有很多实体)。所以我决定把“实体”分成两部分

  1. 将在组响应中返回的一些一般信息 -实体
  2. 将在另一个 Web 服务操作中返回的更详细信息,特定于实体 - EntityDetails

因此,更改后的架构如下(EntityDetails 继承自 Entity):

<element name="GetEntitiesRequest" type="Something"/>
<element name="GetEntitiesResponse" type="Entities"/>

<complexType name="Entities">
    <sequence>
        <element name="Entity" type="Entity" minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
</complexType>

<complexType name="Entity">
    <sequence>
        (...)
    </sequence>
</complexType>

<element name="GetEntityDetailsRequest" type="SomethingMore"/>
<element name="GetEntityDetailsResponse" type="EntityDetails"/>

<complexType name="EntityDetails">
    <complexContent>
        <extension base="Entity">
            <sequence>
                (...)
            </sequence>
        </extension>
    </complexContent>
</complexType>

JAXB(准确地说:hyperjaxb3)为 Entity(继承策略 = JOINED)、EntityDetails 和 Entities 生成类。此外,它使用“createGetEntitiesResponse”方法创建ObjectFactory 。我正在使用这种方法来编组通过 Hibernate 从实体表中检索到的列表。

理论上,我应该在发送“GetEntitiesRequest”时得到“ Entity ”列表。但是,我得到了“ EntityDetails ”列表。

如果您从一开始就阅读此表格,您可以想象,这是我想要避免的。

如果您需要更多详细信息,persistence.xml 如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence (...)>
    <persistence-unit name="org.package">
        <class>org.package.Entity</class>
        <class>org.package.EntityDetails</class>
        <class>org.package.Entities</class>
    </persistence-unit>
</persistence>

我使用 Gradle 进行构建自动化,并使用它的 jaxb 插件来生成类:

jaxb 
{
    xsdDir = "src/main/webapp/schemas/messages"
    bindingsDir = "src/main/webapp/schemas/bindings"
    bindings = ["bindings.xjb"]
    xjc 
    {
        extension = true
        taskClassname = "com.sun.tools.xjc.XJC2Task"
        generatePackage = "org.package"
        args = ["-Xannotate", "-Xhyperjaxb3-jpa2", "-Xequals", "-XhashCode", "-XtoString"]
    }
}

目前,bindings.xjb,除了标题,只包含:

<jaxb:globalBindings localScoping="toplevel">
    <xjc:serializable/>
</jaxb:globalBindings>
4

1 回答 1

0

首先,确保您Entity从数据库中获取实例,而不是EntityDetails

尝试创建一个没有数据库的隔离场景。只需实例化你的Entity,用一些东西填充它,创建响应并编组它。走着瞧吧。您将隔离问题 - 您从数据库中获取了错误的实例,或者编组无法按预期工作。如果没有看到您的代码,两者都很难诊断。尝试将您的问题减少到我上面提到的两个之一。

免责声明:我是 Hyperjaxb3 的作者。

于 2014-09-14T22:24:56.063 回答