简体   繁体   中英

Accessing SOAP web service with incorrect wsdl

Background:

I need to consume an existing web service (SOAP over http) that has a couple of issues:

1) The wsdl on the server doesn't even resemble the web service as described in their documentation, which includes a completely different wsdl file

2) The wsdl file provided with their documentation seems to come close to describing the web service on the server, but when I generated java client code using cxf and used it to access the web service, cxf throws exceptions like the following

 javax.xml.bind.UnmarshalException: unexpected element (uri:"http://us-labs.companyxyz.com/", local:"searchResponse"). Expected elements are <{http://companyxyz.com/xyz-xml/2.0/}searchResponse>
... 33 more

I'm no SOAP expert, but assuming this means the namespaces in their response don't match those defined in the wsdl.

Since my application is written in java, I was able to connect and get a response using commons http client and a handcrafted SOAP request, so worst case I can fall back to that and parse the response to get what I need.

My questions:

  1. Did I interpret the exception correctly?
  2. If no: any suggestions on how I can debug this?
  3. If yes: can anyone suggest better alternatives to handcrafting http requests and parsing xml by hand? (Getting correct wsdl is, unfortunately, not an option)

Thanks in advance.

  1. Most likely. The response is using the namespace "http://us-labs.companyxyz.com/", but in the WSDL, the same element is declared with namespace "http://companyxyz.com/xyz-xml/2.0/".

  2. I'm not familiar with CXF, but other SOAP frameworks usually offer some kind of logging capabilities. It would probably help you if the SOAP requests and responses are logged somewhere for more specific analysis.

  3. Why is it not an option to get a correct WSDL? If you really are able to "handcraft" correct SOAP requests and expect to be able to "handparse" the responses, you should be able to write the WSDL yourself as well. Of course, the WSDL should be provided to you by the service operator, but if you mean that noone is able to provide you with a correct WSDL, I would consider writing it myself instead of creating and parsing the SOAP messages manually.

I think you interpreted the exception correctly - the namespace is different than expected.

It is also not really unexpected. it is a fact of life that vendor supplied wsdls are not always correct. We actually write our own WSDLs and XSDs for vendor applications for just that reason.

You can use your own WSDL even run-time. There are some SO questions on that, here and here .

You could also have a look here . I haven't tried it, but it could work.

We actually extend the generated service and create a port supplying a WSDL located on the classpath using the JaxWS Service constructor . That works fine for us.

We debug CXF by dumping the incoming and outgoing messages. There seem to be quite a lot of methods to do just that. We use either a proxy between de web service and our client, or recently a cxf.xml file somewhere. Using a -D flag we temprarily configure this.

-Dcxf.config.file=/home/me/cxf-debug.xml 

and cxf-debug.xml contains something like :

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:cxf="http://cxf.apache.org/core"
      xsi:schemaLocation="
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <cxf:bus>
        <cxf:features>
            <cxf:logging/>
        </cxf:features>
    </cxf:bus> 
</beans>

http://cxf.apache.org/docs/debugging-and-logging.html

Both responses suggested the same basic approach, which turned out to be the correct one. I fixed the provided wsdl to make it match the web service, and I was able to use cxf, which saved me a lot of hand coding.

The main problem with their wsdl was in fact a namespace issue. The essence of the problem was as follows: their wsdl defined two namespaces, both of which have a "searchResponse" element.

{http://us-labs.companyxyz.com/}searchResponse

was defined in the wsdl to contain 0 or more

{http://companyxyz.com/xyz-xml/2.0/}searchResponse

But in their response the nested searchResponse wasn't qualified by {http://companyxyz.com/xyz-xml/2.0/} so cxf interpreted it as a {http://us-labs.companyxyz.com/}searchResponse

I fixed it by introducing a new type.

Thanks to both responders.

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