在 Jax-WS 客户端中解析 Soap 日期
Parsing Soap dates in Jax-WS Client
我正在使用 Jax-WS 访问 SOAP 服务,但我在处理一种数据类型时遇到困难:
<xs:complexType name="OurDateType">
<xs:sequence>
<xs:element name="Day" type="xs:gDay" minOccurs="0">
</xs:element>
<xs:element name="Month" type="xs:gMonth">
</xs:element>
<xs:element name="Year" type="xs:gYear">
</xs:element>
</xs:sequence>
</xs:complexType>
客户端存根是自动生成的,它为每个 Day
、Month
和 Year
生成一个带有 XmlGregorianCalendar
字段的类型:
public class OurDateType {
@XmlElement(name = "Day")
@XmlSchemaType(name = "gDay")
protected XMLGregorianCalendar day;
@XmlElement(name = "Month", required = true)
@XmlSchemaType(name = "gMonth")
protected XMLGregorianCalendar month;
@XmlElement(name = "Year", required = true)
@XmlSchemaType(name = "gYear")
protected XMLGregorianCalendar year;
SOAP 调用无法从返回的 XML 中解组此结构:
<TheDate xsi:type="ns1:OurDateType">
<Month xsi:type="xsd:gMonth">10</Month>
<Year xsi:type="xsd:gYear">2011</Year>
</TheDate>
错误是SOAP exception: Unmarshalling Error: 10
。
我已经尝试创建一个 package-info.java
文件来覆盖解组,但存在以下问题:
wsimport
创建一个 package-info.java
文件。由于同一个包不能包含两个 `package-info.java 实例,我必须编辑生成的代码。
- 之后,我的适配器 class 被传递一个字符串进行解组,没有任何上下文来判断这是一天、一个月还是一年。
是否可以覆盖代码生成并提供我自己的 class 来捕获此类型,或者以了解原始 XML 模式类型的方式覆盖解组?我更改版本的能力有限,因为代码还作为其他三个 SOAP 服务的客户端工作,并为其自己的客户端提供 SOAP 服务。
作为参考,这里是代码生成的配置:
<plugin>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<xadditionalHeaders>true</xadditionalHeaders>
<verbose>true</verbose>
<sourceDestDir>${project.build.directory}/generated-sources/jaxws/wsimport</sourceDestDir>
<staleFile>${project.build.directory}/generated-sources/jaxws/wsimport/stale/.staleFlag</staleFile>
<wsdlDirectory>${basedir}/src/main/resources/wsdl</wsdlDirectory>
<sei/>
</configuration>
</plugin>
我自己回答了,从不同的方向搜索。可以使用 JAXB 绑定文件覆盖生成的代码。 wsimport
将自动使用在 src/jaxws
.
中找到的具有 .xml
扩展名的绑定文件
我放弃了 XmlGregorianCalendar,而是将每个日期元素解析为一个单独的整数。这适用于我的服务,但需要自定义解析器来处理一些允许的日期字段变体。
我使用的绑定文件是这样的:
<globalBindings>
<javaType name="java.lang.Integer" xmlType="xs:gDay"
parseMethod="javax.xml.bind.DatatypeConverter.parseInt"
printMethod="javax.xml.bind.DatatypeConverter.printInt"
/>
<javaType name="java.lang.Integer" xmlType="xs:gMonth"
parseMethod="javax.xml.bind.DatatypeConverter.parseInt"
printMethod="javax.xml.bind.DatatypeConverter.printInt"
/>
<javaType name="java.lang.Integer" xmlType="xs:gYear"
parseMethod="javax.xml.bind.DatatypeConverter.parseInt"
printMethod="javax.xml.bind.DatatypeConverter.printInt"
/>
</globalBindings>
</bindings>
我正在使用 Jax-WS 访问 SOAP 服务,但我在处理一种数据类型时遇到困难:
<xs:complexType name="OurDateType">
<xs:sequence>
<xs:element name="Day" type="xs:gDay" minOccurs="0">
</xs:element>
<xs:element name="Month" type="xs:gMonth">
</xs:element>
<xs:element name="Year" type="xs:gYear">
</xs:element>
</xs:sequence>
</xs:complexType>
客户端存根是自动生成的,它为每个 Day
、Month
和 Year
生成一个带有 XmlGregorianCalendar
字段的类型:
public class OurDateType {
@XmlElement(name = "Day")
@XmlSchemaType(name = "gDay")
protected XMLGregorianCalendar day;
@XmlElement(name = "Month", required = true)
@XmlSchemaType(name = "gMonth")
protected XMLGregorianCalendar month;
@XmlElement(name = "Year", required = true)
@XmlSchemaType(name = "gYear")
protected XMLGregorianCalendar year;
SOAP 调用无法从返回的 XML 中解组此结构:
<TheDate xsi:type="ns1:OurDateType">
<Month xsi:type="xsd:gMonth">10</Month>
<Year xsi:type="xsd:gYear">2011</Year>
</TheDate>
错误是SOAP exception: Unmarshalling Error: 10
。
我已经尝试创建一个 package-info.java
文件来覆盖解组,但存在以下问题:
wsimport
创建一个package-info.java
文件。由于同一个包不能包含两个 `package-info.java 实例,我必须编辑生成的代码。- 之后,我的适配器 class 被传递一个字符串进行解组,没有任何上下文来判断这是一天、一个月还是一年。
是否可以覆盖代码生成并提供我自己的 class 来捕获此类型,或者以了解原始 XML 模式类型的方式覆盖解组?我更改版本的能力有限,因为代码还作为其他三个 SOAP 服务的客户端工作,并为其自己的客户端提供 SOAP 服务。
作为参考,这里是代码生成的配置:
<plugin>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<xadditionalHeaders>true</xadditionalHeaders>
<verbose>true</verbose>
<sourceDestDir>${project.build.directory}/generated-sources/jaxws/wsimport</sourceDestDir>
<staleFile>${project.build.directory}/generated-sources/jaxws/wsimport/stale/.staleFlag</staleFile>
<wsdlDirectory>${basedir}/src/main/resources/wsdl</wsdlDirectory>
<sei/>
</configuration>
</plugin>
我自己回答了,从不同的方向搜索。可以使用 JAXB 绑定文件覆盖生成的代码。 wsimport
将自动使用在 src/jaxws
.
.xml
扩展名的绑定文件
我放弃了 XmlGregorianCalendar,而是将每个日期元素解析为一个单独的整数。这适用于我的服务,但需要自定义解析器来处理一些允许的日期字段变体。
我使用的绑定文件是这样的:
<globalBindings>
<javaType name="java.lang.Integer" xmlType="xs:gDay"
parseMethod="javax.xml.bind.DatatypeConverter.parseInt"
printMethod="javax.xml.bind.DatatypeConverter.printInt"
/>
<javaType name="java.lang.Integer" xmlType="xs:gMonth"
parseMethod="javax.xml.bind.DatatypeConverter.parseInt"
printMethod="javax.xml.bind.DatatypeConverter.printInt"
/>
<javaType name="java.lang.Integer" xmlType="xs:gYear"
parseMethod="javax.xml.bind.DatatypeConverter.parseInt"
printMethod="javax.xml.bind.DatatypeConverter.printInt"
/>
</globalBindings>
</bindings>