版权声明:《==study hard and make progress every day==》 https://blog.csdn.net/qq_38225558/article/details/85293179
什么是拦截器??
就是在客服端访问服务端的时候,在期间添加拦截器完成一些额外的功能。而CXF已经提供了一些日志拦截器,可以直接使用。
添加自带拦截器 - 日志拦截器
LoggingInInterceptor – 信息输入时的拦截器 - 请求
LoggingOutInterceptor – 信息输出时的拦截器 - 响应
继上一篇博客写 WebService - CXF入门 简单的服务端和客户端
服务端添加日志拦截器
public class PublishService {
public static void main(String[] args) {
// 1.创建JaxWsServerFactoryBean的对象,用于发布服务
JaxWsServerFactoryBean serverFactoryBean = new JaxWsServerFactoryBean();
// 2.设置服务发布地址
serverFactoryBean.setAddress("http://127.0.0.1:8080/getWeather");
// 3.设置服务发布的接口
serverFactoryBean.setServiceClass(IWeatherService.class);
// 4.设置服务的发布对象
serverFactoryBean.setServiceBean(new WeatherServiceImpl());
//在发布服务之前配置服务端的拦截器 - 输出输入
serverFactoryBean.getInInterceptors().add(new LoggingInInterceptor());
serverFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
// 5.使用create方法发布服务
serverFactoryBean.create();
System.out.println("服务发布成功...");
}
}
服务端运行发布服务,客户端走一波,再看服务端打印如下日志
客户端添加日志拦截器
public class ClientTest {
public static void main(String[] args) {
// 1.创建JaxWsProxyFactoryBean的对象,用于接收服务
JaxWsProxyFactoryBean proxyFactoryBean = new JaxWsProxyFactoryBean();
// 2.设置服务的发布地址,表示去哪里过去服务
proxyFactoryBean.setAddress("http://127.0.0.1:8080/getWeather");
// 3.设置服务的发布接口,使用本地的代理接口
proxyFactoryBean.setServiceClass(IWeatherService.class);
//在获取服务实例之前配置拦截器
proxyFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
proxyFactoryBean.getInInterceptors().add(new LoggingInInterceptor());
// 4.通过create方法返回接口代理实例
IWeatherService service = (IWeatherService) proxyFactoryBean.create();
// 5.调用远程方法
System.out.println(service.getWeather("成都"));
}
}
服务端运行发布服务,客户端走一波,再看客户端打印如下日志
添加自定义拦截器
步骤:
①声明一个类,来充当拦截器 - 这个类需要继承或实现某个接口或基类
②完成拦截器的逻辑
③把拦截器配置到环境中
服务端添加权限验证进去拦截器
public class AuthInfoInInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
public AuthInfoInInterceptor() { super(Phase.PRE_INVOKE); }
@Override
public void handleMessage(SoapMessage message) throws Fault {
//做事情
//获取到Header中username和password
Header header = message.getHeaders().get(0);
Element root = (Element) header.getObject();
//username
NodeList usernameNodeList = root.getElementsByTagName("username");
Node usernameNode = usernameNodeList.item(0);
String username = usernameNode.getTextContent();
// password
NodeList passwordNodeList = root.getElementsByTagName("password");
Node passwordNode = passwordNodeList.item(0);
String password = passwordNode.getTextContent();
if(!("admin".equals(username)&&"admin".equals(password))){
throw new Fault(new IllegalArgumentException("用户名或密码错误"));
}
System.out.println("通过验证了......");
}
}
服务端发布服务器前添加
客户端添加权限出去拦截器
/**
* 权限出去拦截器
* 配置在客户端,将用户名和密码写到soap中
* @author 郑清
*/
public class AuthenInfoOutInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
private String username;
private String password;
public AuthenInfoOutInterceptor(String username, String password) {
super(Phase.PREPARE_SEND);
this.username = username;
this.password = password;
}
/**
* <soap:Header>
<authInfo>
<username>admin</username>
<password>admin</password>
<authInfo>
<soap:Header>
*
*/
@Override
public void handleMessage(SoapMessage message) throws Fault {
Document doc = DOMUtils.createDocument();
Element root = doc.createElement("authInfo");//根节点
Element usernameEle = doc.createElement("username");//username节点
usernameEle.setTextContent(username);
Element passwordEle = doc.createElement("password");//password节点
passwordEle.setTextContent(password);
//将username和password节点添加到根节点中
root.appendChild(usernameEle);
root.appendChild(passwordEle);
//随便写
QName q = new QName("zq");
Object o = root;//就是要添加的节点对象
Header header = new Header(q, o);
message.getHeaders().add(header );//将username和password写到soap中
}
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
客户端测试类中加入自定义拦截器
服务端运行,客户端测试打印结果如下