简体   繁体   中英

Apache CXF Client generated from inaccurate WSDL

I am creating an Apache CXF client from a WSDL that has been provided from a third party. When I exercise the web service in test I find that the output from the service does not conform to the WSDL.

So far it seems like, for some elements, the WSDL does not define them as nillable=true while the service actually does return them with xsi:nil="true"

My CXF client fails to unmarshall the returned xml and blows up.

I have worked around it to an extent ( by editing the supplied wsdl ), but I don't see that as being a viable solution. The third party are also refusing to bring their service and wsdl definitions in to line, saying that other clients are handling this correctly in production.

So, is there a way to make the unmarshalling of the response less strict? What other avenues could I approach this problem by?

The schema definition of one of the fields that gives me a problem is as follows :

<xsd:element name="cardExpireDate" type="xsd:date"></xsd:element>

This field is returned by the service ( when called in SoapUI ) as <cardExpireDate xsi:nil="true"/>

When my code tries calls the web service I get the following error ( which is way down the stack trace but I believe is the root of the problem )

Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[com.sun.istack.SAXParseException2; lineNumber: 1; columnNumber: 1515; ]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:483)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:417)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:394)
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.doUnmarshal(JAXBEncoderDecoder.java:855)
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.access$100(JAXBEncoderDecoder.java:102)

snip ....

Caused by: javax.xml.bind.UnmarshalException: 
 - with linked exception:
[java.lang.IllegalArgumentException: ]
    ... 92 more
Caused by: java.lang.IllegalArgumentException: 
    at org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parseYear(Unknown Source)
    at org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parse(Unknown Source)

and column 1515 of the document I'm trying to parse is

<cardExpireDate xsi:nil="true"/>

If only date fields are a problem, you can use a custom binding to use org.apache.cxf.xjc.runtime.DataTypeAdapter from cxf-xjc-runtime:

<jaxws:bindings wsdlLocation="YOUR_WSDL_LOCATION"
          xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
          xmlns:xs="http://www.w3.org/2001/XMLSchema"
          xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
          xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <jaxws:bindings  node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='THE_NAMESPACE_OF_YOUR_SCHEMA']">
      <jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <jxb:javaType name="java.util.Date" xmlType="xs:dateTime"
                      parseMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDateTime"
                      printMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.printDateTime"/>
      </jxb:globalBindings>
  </jaxws:bindings>
</jaxws:bindings>

Take a look at the FAQ section at the bottom of http://cxf.apache.org/docs/wsdl-to-java.html if you don't know how to apply the binding.

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