3

JAXB を使用して、定義されたスキーマに基づいて xml ドキュメントをマーシャリング/アンマーシャリングしています。私が気付いているのは、マーシャリングされた xml で JAXB が誤った名前空間を生成していることです。

詳細はこちら-

soap.xsd -->

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope" 
    xmlns:svc="http://abc.com/ServiceSetupV001"
    targetNamespace="http://schemas.xmlsoap.org/soap/envelope"
    elementFormDefault="qualified" attributeFormDefault="unqualified">

    <xsd:import namespace="http://abc.com/ServiceSetupV001" schemaLocation="schema1.xsd" />

    <xsd:complexType name="Envelope">
        <xsd:sequence minOccurs="0" maxOccurs="1">
            <xsd:element name="Body" type="soapenv:Body" minOccurs="0" maxOccurs="1" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="Body">
        <xsd:sequence minOccurs="0" maxOccurs="1">
            <xsd:element name="detailsRequest" type="svc:DetailsRequest" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="detailsResponse" type="svc:DetailsResponse" minOccurs="0" maxOccurs="1" />
        </xsd:sequence>
    </xsd:complexType>

</xsd:schema>

schema1.xsd -->

<xsd:schema 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://abc.com/ServiceSetupV001" 
    xmlns:svc="http://abc.com/ServiceSetupV001" 
    xmlns:osa="http://abc.com/xmlschema/osa" 
    elementFormDefault="qualified" attributeFormDefault="unqualified">

    <xsd:import namespace="http://abc.com/xmlschema/osa" schemaLocation="schema2.xsd"/>

    <xsd:complexType name="DetailsRequest">
        <xsd:sequence minOccurs="0" maxOccurs="1">
            <xsd:element name="requestHeader" type="osa:RequestHeader" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:element name="detailsRequest" type="svc:DetailsRequest" />

    <xsd:complexType name="DetailsResponse">
        <xsd:sequence minOccurs="0" maxOccurs="1">
            <xsd:element name="responseHeader" type="osa:ResponseHeader" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:element name="detailsResponse" type="svc:DetailsResponse" />

</xsd:schema>

schema2.xsd -->

 <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns:osa="http://abc.com/xmlschema/osa" 
        targetNamespace="http://abc.com/xmlschema/osa" 
        elementFormDefault="qualified" attributeFormDefault="unqualified">

        <xsd:complexType name="RequestHeader">
            <xsd:sequence>
                <xsd:element name="component" type="string" />
                <xsd:element name="channel" type="string" />
                <xsd:element name="serverInstance" type="string" minOccurs="0" />
                <xsd:element name="traceId" type="string" />
                <xsd:element name="applicationId" type="string" />
                <xsd:element name="userId" type="string" minOccurs="0" />
                <xsd:element name="userIdType" type="string" minOccurs="0" />
                <xsd:element name="role" type="string" minOccurs="0" />
                <xsd:element name="timestamp" type="dateTime" minOccurs="0" />
                <xsd:element name="isReplyExpected" type="boolean" minOccurs="0" />
            </xsd:sequence>
        </xsd:complexType>

        <xsd:complexType name="ResponseHeader">
            <xsd:sequence>
                <xsd:element name="component" type="string" />
                <xsd:element ref="osa:service" />
                <xsd:element name="traceId" type="string" />
                <xsd:element name="serverInstance" type="string" />
                <xsd:element name="timestamp" type="dateTime" />
            </xsd:sequence>
        </xsd:complexType>

        <xsd:element name="service" type="osa:Service" />
        <xsd:complexType name="Service">
            <xsd:sequence>
                <xsd:element name="name" type="string" />
                <xsd:element name="operation" type="string" />
                <xsd:element name="version" type="string" />
            </xsd:sequence>
        </xsd:complexType>  

    </xsd:schema>

jaxbMarshaller の namespacePrefixMapperImpl を (Spring 構成で) 定義しました。これは、URI を定義済みのプレフィックス名にマップします。

整列化された応答 xml は次のようになります。JAXB が名前空間の接頭辞を間違えていることに注意してください。JAXB は、svc プレフィックスの代わりに、detailsResponse 複合型に soapenv 名前空間を使用しています。次に、osa プレフィックスの代わりに、responseHeader 複合型に svc プレフィックスを使用しています。一部の要素は文字列型であるため、プレフィックスを付けないでください (つまり、デフォルトの名前空間)。等々...

どこで私は間違えましたか?それとも、これは jaxb-impl の問題ですか。

生成された XML -->

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope"
xmlns:osa="http://abc.com/xmlschema/osa"
xmlns:svc="http://abc.com/ServiceSetupV001">
    <soapenv:Body>
        <soapenv:detailsResponse>
            <svc:responseHeader>
                <osa:component/>
                <osa:service/>
                <osa:traceId>sadasdas</osa:traceId>
                <osa:serverInstance>40d501</osa:serverInstance>
                <osa:timestamp>2012-07-01T02:18:00.693Z</osa:timestamp>
            </svc:responseHeader>
        </soapenv:detailsResponse>
    </soapenv:Body>
</soapenv:Envelope>

スキーマから JAXB クラスを生成するために使用しているプラ​​グインは、pom.xml で次のように定義されています。

<!-- Plugin to generate jaxb classes from xsd -->
<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.8.2</version>
    <executions>
        <execution>
            <id>process-xsd</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
                <schemaIncludes>
                    <include>**/*.xsd</include>
                </schemaIncludes>
                <bindingIncludes>
                    <include>**/*.xjb</include>
                </bindingIncludes>
                <generateDirectory>${src.dir}</generateDirectory>
                    <verbose>true</verbose>
                <extension>true</extension>
                <args>
                    <arg>-Xannotate</arg>
                </args>
                <plugins>
                    <plugin>
                        <groupId>org.jvnet.jaxb2_commons</groupId>
                        <artifactId>jaxb2-basics-annotate</artifactId>
                        <version>0.6.4</version>
                    </plugin>
                </plugins>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.2.6</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2.6</version>
        </dependency>       
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>stax</groupId>
            <artifactId>stax-api</artifactId>
            <version>1.0.1</version>
        </dependency>
        <dependency>
            <groupId>activesoap</groupId>
            <artifactId>jaxb-xercesImpl</artifactId>
            <version>1.5</version>
        </dependency>                   
    </dependencies>             
</plugin>
4

1 に答える 1

2

インポートされた子要素には独自の名前空間がありますが、Jaxb はインポートされた子要素を含む xsd のターゲット名前空間を保持しているようです。これを修正する 1 つの方法は、スキーマ内のインポートされた要素の定義を「type」から「ref」に変更することです。

ただし、この場合、クライアントからのスキーマを変更したくないので、機能させるためにスキーマを変更したくありません。

したがって、bindings.xjb ファイルに以下の注釈を追加しました。生成されたスキーマ クラスの要素に正しい名前空間宣言があることがわかります。しかし、問題は、名前空間が正しいにもかかわらず、生成された xml が子要素を生成しないことです。

だから、私はまたちょっと立ち往生しています。これがこんなに大変だとは思いませんでした。

私の bindings.xjb への変更:

<jaxb:bindings node="//xsd:complexType[@name='Body']//xsd:element[@name='detailsRequest']">
    <annox:annotate target="field">
    <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" 
        name="detailsRequest" 
        namespace="http://abc.com/ServiceSetupV001"/>
    </annox:annotate>            
<jaxb:bindings node="//xsd:complexType[@name='Body']//xsd:element[@name='detailsResponse']">
    <annox:annotate target="field">
    <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" 
        name="detailsResponse" 
        namespace="http://abc.com/ServiceSetupV001"/>
    </annox:annotate>            
</jaxb:bindings>        

<jaxb:bindings node="//xsd:complexType[@name='DetailsRequest']//xsd:element[@name='requestHeader']">
    <annox:annotate target="field">
    <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" 
        name="requestHeader" 
        namespace="http://abc.com/xmlschema/osa"/>
    </annox:annotate>            
<jaxb:bindings node="//xsd:complexType[@name='DetailsResponse']//xsd:element[@name='responseHeader']">
    <annox:annotate target="field">
    <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" 
        name="responseHeader" 
        namespace="http://abc.com/xmlschema/osa"/>
    </annox:annotate>            
</jaxb:bindings>

生成されたクラスには適切な名前空間の注釈があります

@XmlElement(name = "detailsRequest", namespace = "http://abc.com/ServiceSetupV001")
protected DetailsRequest detailsRequest;

@XmlElement(name = "detailsResponse", namespace = "http://abc.com/ServiceSetupV001")
protected DetailsResponse detailsResponse;

しかし、マーシャリングされた XML には値がありません。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope"
xmlns:osa="http://abc.com/xmlschema/osa"
xmlns:svc="http://abc.com/ServiceSetupV001">
    <soapenv:Body>
        <svc:detailsResponse/>
    </soapenv:Body>
</soapenv:Envelope>
于 2012-08-15T18:46:10.753 に答える