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>