WebService服务端拦截器,和soap信息格式

原创
2016/05/02 16:09
阅读数 2.8K
webservice写的程序任何客户端都能调用,和语言无关,考虑到系统的安全性稳定性,和某些利益关系,可以考虑webservice的
拦截器控制.webservice的调用过程如下图:

如果不用cxf框架,soap消息的生成,解析都是由程序员自己负责,无论是添加用户名,密码还是提取用户名密码等信息,都是由
程序员的代码完成,如果用了cxf框架,soap消息的生成,解析都是有cxf框架完成
为了进行权限控制,我们可以在服务端要求input消息必须带入验证信息如:用户名,密码等,如果验证错误,就拒绝调用


拦截器:
   cxf的拦截器可以让程序员修改框架生成的soap信息.

cxf拦截器的实现方式,下图介绍:

服务端代码:

/**
 * @author xp
 * @Title: WebServicePublish.java
 * @Package com.xp.cn
 * @Description: TODO
 * @date 2016年4月30日 下午9:06:49
 * @version V1.0  
 */
package com.xp.cn;

import javax.xml.ws.Endpoint;




import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.jaxws.EndpointImpl;

import com.xp.cn.ws.IWebServiceDemo;
import com.xp.cn.ws.impl.WebServiceImpl;


/**
 * @author xp
 * @ClassName: WebServicePublish
 * @Description: TODO
 * @date 2016年4月30日 下午9:06:49
 *
 */
public class WebServicePublish {
	public static void main(String[] args) {
		IWebServiceDemo demo = new WebServiceImpl();
		//调用EndPoint发布服务
		EndpointImpl endPoint = (EndpointImpl) Endpoint.publish("http://127.0.0.1/XXX", demo);
		//自定义拦截器实现Interceptor接口,实际上我们一般会继承AbstractPhaseInterceptor
		//添加服务端in拦截去
		endPoint.getInInterceptors().add(new LoggingInInterceptor());
		//添加服务端out连接器
		endPoint.getOutInterceptors().add(new LoggingInInterceptor());
	}
}

服务端代码永远是in拦截器先起作用,再是out拦截器

运行客户端后,服务端控制台打印信息:

----------------------------
ID: 1
Address: http://127.0.0.1/XXX?wsdl
Http-Method: GET
Content-Type: 
Headers: {Accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], connection=[keep-alive], Content-Type=[null], Host=[127.0.0.1], User-Agent=[Java/1.7.0_40]}
--------------------------------------
五月 02, 2016 6:01:02 下午 org.apache.cxf.services.webServiceImpl.WebServiceImplPort.IWebServiceDemo
信息: Inbound Message
----------------------------
ID: 2
Address: http://127.0.0.1/XXX?wsdl=IWebServiceDemo.wsdl
Http-Method: GET
Content-Type: 
Headers: {Accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], connection=[keep-alive], Content-Type=[null], Host=[127.0.0.1], User-Agent=[Java/1.7.0_40]}
--------------------------------------

ID:1和ID2分别是客户端得到wsdl文档
----------------------------
ID: 3
Address: http://127.0.0.1/XXX
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[text/xml, multipart/related], connection=[keep-alive], Content-Length=[193], content-type=[text/xml; charset=UTF-8], Host=[127.0.0.1], SOAPAction=[""], User-Agent=[JAX-WS RI 2.2.4-b01]}
Payload: 
<?xml version="1.0" ?>
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
        <S:Body>
            <ns2:sayHello xmlns:ns2="http://ws.cn.xp.com/">
                <arg0>xp</arg0>
                </ns2:sayHello>
         </S:Body>
    </S:Envelope>
--------------------------------------
五月 02, 2016 6:01:02 下午 org.apache.cxf.services.webServiceImpl.WebServiceImplPort.IWebServiceDemo
信息: Outbound Message
---------------------------
ID: 3
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: 
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        <soap:Body>
            <ns2:sayHelloResponse xmlns:ns2="http://ws.cn.xp.com/">
                <return>你好xpMon May 02 18:01:02 CST 2016</return>
            </ns2:sayHelloResponse>
     </soap:Body>
</soap:Envelope>
--------------------------------------
第一个ID对应的信息是调用消息sayHello,调用参数是xp
第二个ID对应的是响应消息sayHelloResponse,响应类容是你好xpMon May 02 18:01:02 CST 2016
如果访问服务端不存在的服务,如在浏览器输入服务返回:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <soap:Fault>
            <faultcode>soap:Server</faultcode>
            <faultstring>
                No binding operation info while invoking unknown method with params unknown.
            </faultstring>
       </soap:Fault>
    </soap:Body>
</soap:Envelope>
服务端抛出异常:
org.apache.cxf.interceptor.Fault: No binding operation info while invoking unknown method with params unknown.
	at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:59)
	at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
	at java.util.concurrent.FutureTask.run(FutureTask.java:262)

表明不存在该服务


可见soap消息格式如下:

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Header>
  ...
  ...
</soap:Header>

<soap:Body>
  ...
  ...
  <soap:Fault>
    ...
    ...
  </soap:Fault>
</soap:Body>

</soap:Envelope>

一条 SOAP 消息就是一个普通的 XML 文档,含下列元素:
必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息
可选的 Header 元素,含头部信息,可选的 SOAP Header 元素可含有关 SOAP 消息的应用程序专用信息(比如认证、支
付等)。如果 Header 元素被提供,则它必须是 Envelope 元素的第一个子元素。
必需的 Body 元素,含所有的调用和响应信息
可选的 Fault 元素,提供有关在处理此消息所发生错误的信息













展开阅读全文
打赏
2
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
2
分享
返回顶部
顶部