背景:
我需要使用现有的 Web 服务(基于 http 的 SOAP),该服务有几个问题:
1) 服务器上的 wsdl 甚至不像他们的文档中描述的 Web 服务,其中包括一个完全不同的 wsdl 文件
2) 随其文档一起提供的 wsdl 文件似乎接近于描述服务器上的 Web 服务,但是当我使用 cxf 生成 Java 客户端代码并使用它来访问 Web 服务时,cxf 抛出如下异常
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
我不是 SOAP 专家,但假设这意味着其响应中的命名空间与 wsdl 中定义的命名空间不匹配。
由于我的应用程序是用java编写的,因此我能够使用commons http客户端和手工制作的SOAP请求进行连接并获得响应,因此最坏的情况是我可以回退到该请求并解析响应以获取所需的内容。
我的问题:
- 我是否正确解释了异常?
- 如果没有:关于如何调试它的任何建议?
- 如果是:任何人都可以建议更好的替代方案来手动制作 http 请求和手动解析 xml?(不幸的是,获得正确的 wsdl 不是一种选择)
提前谢谢。
-
最有可能。响应使用命名空间"http://us-labs.companyxyz.com/",但在 WSDL 中,使用命名空间"http://companyxyz.com/xyz-xml/2.0/"声明相同的元素。
-
我不熟悉 CXF,但其他 SOAP 框架通常提供某种日志记录功能。如果将 SOAP 请求和响应记录在某个位置以进行更具体的分析,可能会对您有所帮助。
-
为什么它不是一个获得正确WSDL的选项?如果您确实能够"手工制作"正确的 SOAP 请求,并期望能够"手动解析"响应,那么您也应该能够自己编写 WSDL。当然,WSDL 应该由服务操作员提供给您,但如果您的意思是没有人能够为您提供正确的 WSDL,我会考虑自己编写它,而不是手动创建和解析 SOAP 消息。
您正确解释了异常 - 命名空间与预期不同。
这也不是真的出乎意料。 事实上,供应商提供的 WSDL 并不总是正确的。实际上,正是出于这个原因,我们为供应商应用程序编写了自己的 WSDL 和 XSD。
您甚至可以在运行时使用自己的 WSDL。 这里有一些关于这个问题的问题。
你也可以看看这里。我还没有尝试过,但它可以工作。
我们实际上扩展了生成的服务,并使用 JaxWS Service 构造函数创建一个端口,提供位于类路径上的 WSDL。这对我们来说很好用。
我们通过转储传入和传出消息来调试 CXF。似乎有很多方法可以做到这一点。我们在 de Web 服务和我们的客户之间使用代理,或者最近在某处使用 cxf.xml 文件。使用 -D 标志,我们临时配置它。
-Dcxf.config.file=/home/me/cxf-debug.xml
和 cxf-debug.xml 包含如下内容:
<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
两种回答都提出了相同的基本方法,结果证明是正确的方法。我修复了提供的 wsdl 以使其与 Web 服务匹配,并且我能够使用 cxf,这为我节省了大量手动编码。
他们的 wsdl 的主要问题实际上是命名空间问题。问题的本质如下:他们的 wsdl 定义了两个命名空间,这两个命名空间都有一个"searchResponse"元素。
{http://us-labs.companyxyz.com/}searchResponse
在 WSDL 中定义为包含 0 或更多
{http://companyxyz.com/xyz-xml/2.0/}searchResponse
但是在他们的响应中,嵌套的搜索响应没有被{http://companyxyz.com/xyz-xml/2.0/}
限定,所以cxf将其解释为一个{http://us-labs.companyxyz.com/}searchResponse
我通过引入一种新类型来修复它。
感谢两位响应者。