简体   繁体   中英

Parsing Soap dates in Jax-WS Client

I'm using Jax-WS to access a SOAP service, and I'm having difficulty with one data type:

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

The client stubs are auto-generated, which produces a type with an XmlGregorianCalendar field for each of Day , Month , and 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;

The SOAP call fails to unmarshal this structure from the returned XML:

<TheDate xsi:type="ns1:OurDateType">
  <Month xsi:type="xsd:gMonth">10</Month>
  <Year xsi:type="xsd:gYear">2011</Year>
</TheDate>

The error is SOAP exception: Unmarshalling Error: 10 .

I've tried creating a package-info.java file to override unmarshalling, but there are the following problems:

  1. wsimport creates a package-info.java file. As the same package cannot contain two instances of `package-info.java, I have to edit the generated code.
  2. After that, my adapter class is passed a string to unmarshal without any context to tell whether this is intended to be a day, month, or year.

Is it possible to override the code generation and provide my own class to capture this type, or to override the unmarshalling in a way that knows the original XML schema type? I'm limited in my ability to change versions, as the code is also working as a client for three other SOAP services, and provides a SOAP service to its own clients.

For reference, here's the configuration for code generation:

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

I've answered it myself, by searching from a different direction. It's possible to override the generated code with a JAXB binding file. wsimport will automatically use binding files with a .xml extension found in src/jaxws .

I have abandoned the XmlGregorianCalendar, and instead parse each date element into a separate integer. This works for my service, but a custom parser would be required to handle some of the date field variants allowed.

The binding file I used was this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM