在项目中由于信息系统众多,需要实现"横向互连,纵向贯通"的建设目标,选定系统之间统一通过WebService方式进行数据交互。
WebService:
WebService是一个平*立,低耦合,自包含的web应用程序,使用开放的XML标准来描述、发布、发现、协调和配置这些应用;依据Webservice规范实施的应用之间,无论应用使用的语言,平台或内部协议,都可以相互交换数据。
Web服务的体系结构是基于Web服务提供者、Web服务请求者、Web服务中介者三个角色和发布、发现、绑定三个动作构建的。简单地说,Web服务提供者就是Web服务的拥有者,它耐心等待为其他服务和用户提供自己已有的功能;Web服务请求者就是Web服务功能的使用者,它利用SOAP消息向Web服务提供者发送请求以获得服务;Web服务中介者的作用是把一个Web服务请求者与合适的Web服务提供者联系在一起,它充当管理者的角色,一般是UDDI。这三个角色是根据逻辑关系划分的,在实际应用中,角色之间很可能有交叉:一个Web服务既可以是Web服务提供者,也可以是Web服务请求者,或者二者兼而有之。
下图显示了Web服务角色之间的关系:其中,“发布”是为了让用户或其他服务知道某个Web服务的存在和相关信息;“查找(发现)”是为了找到合适的Web服务;“绑定”则是在提供者与请求者之间建立某种联系。
目前,Apache开源的WebService项目中,Axis/Axis2、CXF是比较主流的框架,性能稳定,功能强大。项目中选用了Axis作为WebService框架。
问题一: 交互规范要求返回报文中增加命名空间的前缀
比如之前我们的response报文节点结构如下:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<SendElectrCostBudgetServiceResponse xmlns="http://abc.com">
<replyCode>OK</replyCode>
</SendElectrCostBudgetServiceResponse>
</soapenv:Body>
</soapenv:Envelope>
<Body>的子节点都没有前缀了...
在网上搜了好多文章,有说是axis1.4自身bug的,有说改服务生成的*_BindingSkeleton.java,*_BindingStub.java的代码,有说在server-config.wsdd中增加enableNamespacePrefixOptimization配置项的,however,我试了可以修改的,都未成功。
后来我换了个思路,在响应报文生成后发送出去之前,做个后置处理。
具体做法是:在server-config.wsdd文件中,全局配置中,增加自定义的Handler,在Handler实现代码中,获取response报文的字符串格式,并增加QName。 有了Handler,在<responseFlow>中配置该Handler,则response报文会得到后置处理。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">问题得以解决。
<soapenv:Body>
<abc:SendElectrCostBudgetServiceResponse xmlns:abc="http://abc.com" xmlns="http://abc.com">
<abc:replyCode>OK</abc:replyCode>
</abc:SendElectrCostBudgetServiceResponse>
</soapenv:Body>
</soapenv:Envelope>