一次困难的web service对接开发

一次艰难的web service对接开发
这次的需求是将我们的系统与一个客户系统对接,对接的方式是通过web service。今天终于基本联调成功了,由于各种主观和客观原因,过程十分艰难,在此记录一下

这次对接,双向的wsdl都是由客户系统提供的,并且没有提供测试的环境,只能我们自己搭建服务端的桩来测试

由于以前用cxf开发过web service应用,过程比较顺利,所以就考虑这回也用cxf来做

先看了一下现有的系统,发现里面已经有cxf2.0.13的jar包了。不过cxf2.0.13版本有点老,想着做个jar包升级应该也是问题不大,所以就草率决定用cxf2.5.2来开发

另外感觉用客户提供的wsdl反向生成的代码很冗余,因为了解过一些wsdl,觉得对着wsdl手写应该也能搞定,所以就没有用反向生成的方式,想自己根据wsdl手写java代码

现在看来,这2个决定都太草率了,最终都造成了返工。整个过程一波三折:

1、jar包冲突

对照着wsdl,很快就手写好了客户端和服务端的代码,包括接口和领域模型。然后配一配cxf和spring的集成,搭了一个桩,一下就弄好了

可是将这部分代码放到项目里验证,用cxf2.5.2.jar替换了cxf2.0.13,就抛异常了:java.lang.IncompatibleClassChangeError: Implementing class

2、jar包升级后,旧功能不好用

好不容易定位出来,原来是2个版本的cxf所依赖的jar包是不同的,将相关的jar包也替换之后,发布成功了。可是系统中原来的几个老功能坏了,看来cxf的版本不能随便替换

3、jar包回退后,新功能不好用

于是又把cxf2.0.13替换了回去,这次老功能是可以了,我们新开发的web service也发布起来了,可是调用的时候报异常:
java.lang.IllegalArgumentException: object is not an instance of declaring class

后来发现,是cxf2.0.13和cxf2.5.2的配置文件的写法不同,改了一下以后,调用成功了

这3个问题的解决方法,见http://kyfxbl.iteye.com/blog/1467354

4、spring注入异常

当我们往服务端web service里注入业务逻辑组件,或者往业务逻辑组件里注入web service客户端接口时,依赖注入经常发生一些奇怪的问题,经常声明的bean找不到什么的

最后通过各种方式解决了,详情见http://kyfxbl.iteye.com/blog/1470923

不过还是遗留了一些问题没想通,以后再慢慢研究

5、根据wsdl手写的代码不好使

由于客户提供的wsdl比较复杂,手写的代码联调不通,最终还是只能用wsdl2java工具来做反向生成

6、用wsdl2java生成的代码,发布失败

生成了代码以后,发布又失败了,报了以下异常
Schema name conflict in collection. Namespace:xxxxxx

又花了1天时间解决了这个问题,详情见http://kyfxbl.iteye.com/blog/1483953

7、https证书问题

经过上面几个步骤,web service是发布起来了,通过http可以调通,但是客户要求用https协议来走,而且要求是双向认证。大家对https都不熟悉,这块花了3天时间才做出来,可以说是最困难的一步

8、实际联调时,客户端校验不通过

搞定了https协议问题之后,终于能业务联调了,可是失败了,客户系统那边报
Error code 'BEA-382505'. OSB Validate action failed validation: Expected element 'requestHeader' instead of 'requestBody' here in element XXX

定位发现原来是我们发送请求的时候,只填写了RequestBody的内容,以为不重要就没有填写RequestHead的内容,所以客户那边校验没通过

把这块改完以后,就OK了

总结一下:

1、开发新功能时,尽量在现有的jar包基础上开发。因为如果用与实际环境不同的jar包,很难保证不会出现jar包冲突,或者影响现有功能的问题

2、根据wsdl手写代码不是那么容易的,对于比较复杂的wsdl,还是用wsdl2java工具会比较保险

3、用spring配置文件来配置cxf还是很容易的,但是当集成spring和cxf的时候,依赖注入要特别小心,会有一些很异常的情况。这块的原因我现在还没有搞清楚