在Jax-WS Client中解析Soap日期

时间:2015-02-06 15:57:45

标签: java soap jax-ws

我正在使用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>

自动生成客户端存根,这会为XmlGregorianCalendarDayMonth生成一个Year字段的类型:

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文件以覆盖解组,但存在以下问题:

  1. wsimport创建一个package-info.java文件。由于同一个包不能包含两个`package-info.java实例,我必须编辑生成的代码。
  2. 之后,我的适配器类被传递给unmarshal一个字符串,没有任何上下文来判断这是一天,一个月还是一年。
  3. 是否可以覆盖代码生成并提供我自己的类来捕获此类型,或以知道原始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>
    

1 个答案:

答案 0 :(得分:0)

我自己通过从不同的方向搜索来回答。可以使用JAXB绑定文件覆盖生成的代码。 wsimport会自动使用.xmlsrc/jaxws扩展名的绑定文件。

我放弃了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>