CXF的拦截器
•为什么设计拦截器?
1.为了在webservice请求过程中,能动态操作请求和响应数据, CXF设计了拦截器.
•拦截器分类:
1.按所处的位置分:服务器端拦截器,客户端拦截器
2.按消息的方向分:入拦截器,出拦截器
3.按定义者分:系统拦截器,自定义拦截器
•拦截器API
Interceptor(拦截器接口)
AbstractPhaseInterceptor(自定义拦截器从此继承)
LoggingInInterceptor(系统日志入拦截器类)
LoggingOutInterceptor(系统日志出拦截器类)
①系统拦截器
服务器端拦截器:
//通过终端类将helloWS对象发布到address上
EndpointImpl endpoint = (EndpointImpl) Endpoint.publish(address, helloWS);
//在服务器端添加一个日志的in拦截器
endpoint.getInInterceptors().add(new LoggingInInterceptor());
//在服务器端添加一个日志的out拦截器
endpoint.getOutInterceptors().add(new LoggingOutInterceptor());
客户端拦截器:
//创建生成SEI实现对象的工厂
HelloWSImplService factory = new HelloWSImplService();
//得到web service的SEI的实现类对象(动态生成的对象)
HelloWS helloWS = factory.getHelloWSImplPort();
//得到客户端对象
Client client = ClientProxy.getClient(helloWS);
//添加客户端的out拦截器
client.getOutInterceptors().add(new LoggingOutInterceptor());
//添加客户端的in拦截器
client.getInInterceptors().add(new LoggingInInterceptor());
String result=helloWS.sayHello("tom")
②自定义拦截器
AbstractPhaseInterceptor:抽象过程拦截器,一般自定义的拦截器都会继承于它
功能:通过自定义拦截器实现用户名和密码的检查
1. 客户端:
设置out拦截器,向soap消息中添加用户名和密码数据
public class AddUserIntercept extends AbstractPhaseInterceptor<SoapMessage> {
private String name;
private String password;
public AddUserIntercept(String name, String pasword) {
super(Phase.PRE_PROTOCOL);
this.name = name;
this.password = pasword;
}
@Override
public void handleMessage(SoapMessage msg) throws Fault {
System.out.println("-----handleMessage");
Document document = DOMUtils.createDocument();
//<atguigu>
Element tgfile= document.createElement("tg");
//<name>tg</name>
Element nameEle = document.createElement("name");
nameEle.setTextContent(name);
//<password>123</password>
Element passwordEle = document.createElement("password");
passwordEle.setTextContent(password);
tgfile.appendChild(nameEle);
tgfile.appendChild(passwordEle);
//添加为请求消息的 头消息<soap:Header> soap 有head ,body等
msg.getHeaders().add(new Header(new QName("tg"), tgfile));
}
}
- 服务器端:
设置in拦截器,从soap消息中获取用户名和密码数据,如果不满足条件就不执行web service的方法
public class MyIntercept extends AbstractPhaseInterceptor<SoapMessage> {
public MyIntercept() {
super(Phase.PRE_PROTOCOL);
}
@Override
public void handleMessage(SoapMessage msg) throws Fault {
System.out.println("-----handleMessage");
Header header = msg.getHeader(new QName("tg"));
if(header==null) {
System.out.println("没有通过拦截器");
throw new Fault(new RuntimeException("用户名密码不存在 "));
} else {
Element data = (Element) header.getObject();
if(data==null) {
throw new Fault(new RuntimeException("用户名密码不存在22"));
} else {
String name = data.getElementsByTagName("name").item(0).getTextContent();
String password = data.getElementsByTagName("password").item(0).getTextContent();
if(!"tg".equals(name) || !"123".equals(password)) {
throw new Fault(new RuntimeException("用户名密码不正确"));
}
}
}
System.out.println("通过拦截器了!");
}
}
- 说明:用户名和密码是以xml片断的形式存放在soap消息中的
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<tg>
<name>tanggao</name>
<password>123</password>
</tg>
</soap:Header>
<soap:Body>
<ns2:getStudentById xmlns:ns2="http://server.ws.java.tg.net/">
<arg0>1</arg0>
</ns2:getStudentById>
</soap:Body>
</soap:Envelope>