JAXB总是编组扩展 - 无法仅获取超类型的元素

时间:2014-09-06 15:30:54

标签: java hibernate jaxb spring-ws hyperjaxb

我遇到了 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
  3. 因此,更改后的架构如下( 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从 Entity 表中检索到的List。

    理论上,我应该在发送“GetEntitiesRequest”时获得“实体”的列表。但是,我得到了“ 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>
    

1 个答案:

答案 0 :(得分:1)

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

尝试创建一个没有数据库的独立场景。只需实例化你的Entity,填写一些创建响应的内容并编组。走着瞧吧。 您将隔离问题 - 要么从数据库中获取错误的实例,要么编组不能按预期工作。如果没有看到你的代码,两者都有点难以诊断。尝试将您的问题减少到我上面提到的两个中的一个。

Diclaimer:我是Hyperjaxb3的作者。