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