4

JAXBを使用して、いくつかのXSDファイルからJavaコードを生成しています。次に、OSGiコンテナー内で、生成されたコードにXMLファイルをアンマーシャリングしています。XSDはxsd:any要素を使用します:

<xsd:complexType name="GetReservationRSType">
    <xsd:sequence>
        <xsd:element name="Errors" type="pnrb:Errors.PNRB"
            minOccurs="0" />
        <xsd:choice>
            <xsd:element name="Reservation" type="pnrb:Reservation.PNRB"
                minOccurs="0" />
            <xsd:element name="Content" minOccurs="0">
                <xsd:complexType>
                    <xsd:choice>
                        <xsd:any processContents="lax" />
                    </xsd:choice>
                </xsd:complexType>
            </xsd:element>
        </xsd:choice>
    </xsd:sequence>
</xsd:complexType>

本番コードで機能させるのにいくつかの問題がありましたが、@ XmlSeeAlsoアノテーションを手動で追加したときに最終的に解決しました(@XmlSeeAlso(value = { OTATravelItineraryRS.class })以下のコードで):

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "GetReservationRSType", propOrder = {
    "warnings",
    "errors",
    "reservation",
    "content"
})
@XmlSeeAlso({
    GetReservationRS.class
})
public class GetReservationRSType {

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "any"
    })
    @XmlSeeAlso(value = { OTATravelItineraryRS.class })
    public static class Content {
       //  ...
    }
    // ...
}

JAXBにそのような注釈を自動的に追加させる方法はありますか?たとえば、いくつかのJAXBバインディング構成オプションを追加するか、XSDファイルを変更しますか?

編集:

OSGi envの私のJAXBContextは、次の方法で初期化されます(生成されたすべてのパッケージ名をパラメーターとして取得します)-いくつかのJAXB関連の投稿で提案されているように、コロン区切り文字を使用してリストされています。

<bean id="jaxbContext" class="javax.xml.bind.JAXBContext" factory-method="newInstance">
    <constructor-arg index="0" value="com.sabre.webservices.pnrbuilder:com.sabre.webservices.sabrexml._2003._07" />    
</bean>      

次の例外が発生します。

Caused by: javax.xml.bind.MarshalException
 - with linked exception:
[javax.xml.bind.JAXBException: class com.sabre.webservices.sabrexml._2003._07.OTATravelItineraryRS nor any of its super class is known to this context.]
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:318)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244)
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:105)
    at org.apache.camel.converter.jaxb.FallbackTypeConverter.marshall(FallbackTypeConverter.java:174)
    at org.apache.camel.converter.jaxb.FallbackTypeConverter.convertTo(FallbackTypeConverter.java:88)
    ... 94 more
Caused by: javax.xml.bind.JAXBException: class com.sabre.webservices.sabrexml._2003._07.OTATravelItineraryRS nor any of its super class is known to this context.
    at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:246)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:261)
    at com.sun.xml.bind.v2.runtime.property.SingleReferenceNodeProperty.serializeBody(SingleReferenceNodeProperty.java:113)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:699)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:152)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:328)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:593)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:320)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:494)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315)
    ... 98 more
Caused by: javax.xml.bind.JAXBException: class com.sabre.webservices.sabrexml._2003._07.OTATravelItineraryRS nor any of its super class is known to this context.
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:590)
    at com.sun.xml.bind.v2.runtime.property.SingleReferenceNodeProperty.serializeBody(SingleReferenceNodeProperty.java:105)
    ... 107 more
4

2 に答える 2

4

満足のいく回避策を見つけました。jaxbannotateプラグインを使用します。おそらくそれは完璧な解決策ではありませんが、少なくとも、生成されたクラスをSVNリポジトリにコミットすることを妨げます。上記のプラグインは、必要な注釈を追加するだけです。

pom.xmlで必要な構成は次のとおりです。

        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>

            <executions>
                <execution>
                    <id>schema-pnr-service</id>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                    <configuration>
                        <schemaDirectory>src/main/resources/xsd</schemaDirectory>
                        <schemaIncludes>
                            <include>GetReservationSTLRQ_v0.01.xsd</include>
                            <include>GetReservationSTLRS_v0.01.xsd</include>
                            <include>OTA_TravelItineraryReadCDI1.0.5RQ.xsd</include>
                            <include>OTA_TravelItineraryReadCDI1.0.5RQRS.xsd</include>
                            <include>OTA_TravelItineraryReadCDI1.0.5RS.xsd</include>
                            <include>OTA_TravelItineraryReadPNR1.0.5RS.xsd</include>
                        </schemaIncludes>
                        <extension>true</extension>
                        <args>
                            <arg>-Xannotate</arg>
                            <arg>-Xannotate-defaultFieldTarget=setter</arg>
                        </args>
                        <plugins>
                            <plugin>
                                <groupId>org.jvnet.jaxb2_commons</groupId>
                                <artifactId>jaxb2-basics-annotate</artifactId>
                            </plugin>
                        </plugins>                            
                    </configuration>
                </execution>
            </executions>
        </plugin>  

また、必要なアノテーションは、*。xsdファイルと同じディレクトリにあるbindings.xjbファイルで構成されます。その内容は次のとおりです。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
                xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
                xmlns:annox="http://annox.dev.java.net" 
                extensionBindingPrefixes="annox" version="2.1">
    <globalBindings typesafeEnumMaxMembers="600"/>

    <bindings schemaLocation="GetReservationSTLRS_v0.01.xsd" node="/xsd:schema">
        <bindings node="xsd:complexType[@name='GetReservationRSType']/xsd:sequence/xsd:choice/xsd:element[@name='Content']/xsd:complexType">
            <annox:annotate target="class">
                <annox:annotate annox:class="javax.xml.bind.annotation.XmlSeeAlso" value="com.sabre.webservices.sabrexml._2003._07.OTATravelItineraryRS" />
            </annox:annotate>           
        </bindings>

    </bindings>    
</bindings>
于 2013-01-16T18:20:59.900 に答える
0

@XmlSeeAlso注釈を強制的に挿入しようとする代わりにJAXBContext、生成されたパッケージ名で を作成する必要があります。このようにして、すべてのクラスが確実に処理されるようにすることができます。あなたはOSGi環境にいるので、パラメータを取るメソッドの1つを使用するために使用してClassLoaderください。

JAXBContext jc = JAXBContext.newInstance("com.example.foo", ObjectFactory.class.getClassLoader());

生成されたパッケージ名が複数ある場合は、コンテキスト パスが:区切られます。

JAXBContext jc = JAXBContext.newInstance("com.example.foo:org.example.bar", ObjectFactory.class.getClassLoader());
于 2013-01-16T13:09:38.233 に答える