1.1)• 为什么设计拦截器?
1. 为了在webservice请求过程中,能动态操作请求和响应数据, CXF设计了拦截器.
• 拦截器分类:
2. 按所处的位置分:服务器端拦截器,客户端拦截器
3. 按消息的方向分:入拦截器,出拦截器
4. 按定义者分:系统拦截器,自定义拦截器
• 拦截器API
Interceptor(拦截器接口)
AbstractPhaseInterceptor(自定义拦截器从此继承)
LoggingInInterceptor(系统日志入拦截器类)
LoggingOutInterceptor(系统日志出拦截器类)
Interceptor是CXF架构中一个重要的功能。你可以在不对核心模块进行修改的情况下,动态添加很多功能(你可以想象Struts2拦截器的优点)。这对于CXF这个以处理消息为中心的服务框架来说是非常有用的,CXF通过在Interceptor中对消息进行特殊处理,实现了很多重要功能模块,例如:日志记录,Soap消息处理,消息的压缩处理。
CXF已经实现了很多种拦截器,很多已经在发布、访问Web 服务时已经默认添加到拦截器链。一般情况下, 我们自己的拦截器只要继承AbstractPhaseInterceptor<T extends org.apache.cxf.message.Message>类即可,这个类可以指定继承它的拦截器在什么阶段被启用,阶段属性可以通过org.apache.cxf.phase.Phase 中的常量指定值。
1.2) 编码实现拦截器
• 使用日志拦截器,实现日志记录
– LoggingInInterceptor
– LoggingOutInterceptor
• 使用自定义拦截器,实现用户名与密码的检验
– 服务器端的in拦截器
– 客户端的out拦截器
– xingmiao/123456
服务端
SEI接口
package com.me.ws;
import javax.jws.WebMethod;
import javax.jws.WebService;
/*
* SEI
*/
@WebService
public interface HelloWS {
@WebMethod
public String sayHello(String name);
}
SEI接口实现类
package com.me.ws;
import javax.jws.WebService;
/*
* SEI的实现
*/
@WebService
public class HelloWSImpl implements HelloWS {
@Override
public String sayHello(String name) {
System.out.println("server sayHello()" + name);
return "Hello " + name;
}
}
CheckUserInterceptor
package com.me.ws.interceptor;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
/**
* 检查用户的拦截器
* @author Administrator
*
*/
public class CheckUserInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
public CheckUserInterceptor() {
super(Phase.PRE_PROTOCOL);
// TODO Auto-generated constructor stub
}
/*
<Envelope>
<head>
<authUser>
<name>xiaoming</name>
<password>123456</password>
</authUser>
<head>
<Body>
<sayHello>
<arg0>xiaoming</arg0>
<sayHello>
</Body>
</Envelope>
*/
@Override
public void handleMessage(SoapMessage message) throws Fault {
Header header = message.getHeader(new QName("authUser"));
if(header!=null){
Element authUser = (Element) header.getObject();
String name = authUser.getElementsByTagName("name").item(0).getTextContent();
String password = authUser.getElementsByTagName("password").item(0).getTextContent();
if("xiaoming".equalsIgnoreCase(name) && "123456".equals(password)){
System.out.println("server 通过认证拦截器。。。");
return ;
}
}
//不能通过
System.out.println("server 没有通过认证拦截器。。。");
throw new Fault(new RuntimeException("请求输入一个正确的用户名密码"));
}
}
发布webService
package com.me.ws.server;
import java.util.List;
import javax.xml.ws.Endpoint;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.message.Message;
import com.me.ws.HelloWSImpl;
import com.me.ws.interceptor.CheckUserInterceptor;
/*
* 发布Web Service
*/
public class ServerTest {
public static void main(String[] args) {
String address = "http://127.0.0.1:8787/cxf/helloWS";
Endpoint endpoint = Endpoint.publish(address, new HelloWSImpl());
System.out.println(endpoint);
EndpointImpl endpointImpl =(EndpointImpl) endpoint;
//服务端日志入拦截器
List<Interceptor<? extends Message>> inInterceptors = endpointImpl.getInInterceptors();
inInterceptors.add(new LoggingInInterceptor());
//服务器添加自定义拦截器
inInterceptors.add(new CheckUserInterceptor());
//服务器日志出拦截器
List<Interceptor<? extends Message>> outInterceptors = endpointImpl.getOutInterceptors();
outInterceptors.add(new LoggingOutInterceptor());
System.out.println("发布webservice成功!");
}
}
客户端
使用cxf工具包生成客户端代码。。。略
AddUserInterceptor
package com.me.ws.Interceptor;
import java.util.List;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class AddUserInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
private String name;
private String password;
public AddUserInterceptor(String name,String password) {
super(Phase.PRE_PROTOCOL);//准备协议化时拦截
// TODO Auto-generated constructor stub
this.name = name;
this.password =password;
}
/*
<Envelope>
<head>
<authUser>
<name>xiaoming</name>
<password>123456</password>
</authUser>
<head>
<Body>
<sayHello>
<arg0>xiaoming</arg0>
<sayHello>
</Body>
</Envelope>
*/
@Override
public void handleMessage(SoapMessage message) throws Fault {
List<Header> headers = message.getHeaders();
/*<authUser>
<name>xiaoming</name>
<password>123456</password>
</authUser> */
Document document = DOMUtils.createDocument();
Element rootEle = document.createElement("authUser");
Element nameEle = document.createElement("name");
nameEle.setTextContent(name);
rootEle.appendChild(nameEle);
Element passwordEle = document.createElement("password");
passwordEle.setTextContent(password);
rootEle.appendChild(passwordEle);
headers.add(new Header(new QName("authUser"), rootEle));
System.out.println("client HandMessage()....");
}
}
测试服务
package com.me.ws.test;
import java.util.List;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.message.Message;
import com.me.ws.HelloWS;
import com.me.ws.HelloWSImplService;
import com.me.ws.Interceptor.AddUserInterceptor;
public class clientTest {
public static void main(String[] args) {
HelloWSImplService factory = new HelloWSImplService();
HelloWS helloWS = factory.getHelloWSImplPort();
//发送请求的客户端对象
Client client = ClientProxy.getClient(helloWS);
//客户端的日志出拦截器
List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors();
outInterceptors.add(new LoggingOutInterceptor());
//客户端添加制定义拦截器
outInterceptors.add(new AddUserInterceptor("xiaoming", "123456"));
//客户端的日志入拦截器
List<Interceptor<? extends Message>> inInterceptors = client.getInInterceptors();
inInterceptors.add(new LoggingInInterceptor());
String hello = helloWS.sayHello("jack");
System.out.println(hello);
}
}