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 元素,提供有关在处理此消息所发生错误的信息