JAXB Impl在编组xml中生成不正确的名称空间

问题描述:

我正在使用JAXB根据定义的模式对xml文档进行编组/解组。我注意到的是,JAXB在编组xml中产生了不正确的命名空间。JAXB Impl在编组xml中生成不正确的名称空间

下面是详细信息 -

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> 

我已经定义了一个namespacePrefixMapperImpl f或jaxbMarshaller(在我的spring配置中),它将URI映射到我定义的前缀名称。

编组响应xml看起来像这样。请注意,JAXB对命名空间前缀进行了大量修改。 JAXB使用soapenv名称空间 来获取detailsResponse复杂类型,而不是svc前缀。然后它使用svc前缀作为responseHeader复杂类型而不是osa前缀。 某些元素是字符串类型的,因此应该没有前缀(即默认名称空间)。等等......

我哪里出错了?或者这是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> 

我使用生成从模式在我的pom.xml中定义的JAXB类如下插件:

<!-- 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> 

嗯,看起来像Jaxb正在为导入的子元素保留包含xsd的目标名称空间,即使这些导入的子元素具有其自己的名称空间。解决这个问题的一种方法是将架构中导入元素的定义从“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>