webserive学习记录5-拦截器完成登陆校验
说说cxf中的拦截器,可以分为系统拦截器(如日志拦截器)和自定义拦截器,也可以分为出拦截器和入拦截器,也可以分为服务器拦截器和客户端拦截器。
下面将实现一个可以进行登陆验证的拦截器,其中用户名作为方法参数传递,密码放在发送给服务器的xml的header中。
服务端
代码结构如下:

ValidUser:

applicationContext

CXFServices
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd"> <!-- 1.使用jaxws:endpoint标签的配置发布一个 webservice 2.用implementor属性配置服务提供实现类
3.address属性配置外部访问的相对路径 4.使用 jaxws:inInterceptors 标签配置2个日志拦截器,用来打印调用时的日志信息
5.注意:在此配置文件中,需加入jaxws与soap命名空间 --> <!-- <import resource="classpath*:META-INF/cxf/cxf.xml" />
<import resource="classpath*:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath*:META-INF/cxf/cxf-servlet.xml" /> --> <bean id="jaxWsServiceFactoryBean" class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
<property name="wrapped" value="true" />
</bean> <jaxws:endpoint id="loginCheckService"
implementor="login.check.ws.impl.LoginCheck" address="/loginCheck">
<jaxws:inInterceptors>
<bean id="inLoggingInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="outLoggingInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<bean id="loginCheckInterceptor" class="login.check.ws.impl.LoginCheck" />
</jaxws:inInterceptors>
<jaxws:serviceFactory>
<ref bean="jaxWsServiceFactoryBean" />
</jaxws:serviceFactory>
</jaxws:endpoint> </beans>
web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>logincheckws</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list> <!-- 加入spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 加入CXF支持 -->
<servlet>
<description>Apache CXF Endpoint</description>
<display-name>cxf</display-name>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping> </web-app>
LoginCheck:继承了AbstractPhaseInterceptor,实现了handleMessage方法,用来从客户端发来soap消息头中获取密码,并会保存在ThreadLocal变量中,供校验用户时使用。
package login.check.ws.impl; import java.util.List; import javax.jws.WebService;
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;
import org.w3c.dom.NodeList; import login.check.constant.ValidUser;
import login.check.ws.interf.ILoginCheck; @WebService(endpointInterface="login.check.ws.interf.ILoginCheck", targetNamespace="http://login.check.ws")
public class LoginCheck extends AbstractPhaseInterceptor<SoapMessage> implements ILoginCheck{ private static final ThreadLocal<String> passwords = new ThreadLocal<>(); public LoginCheck() {
super(Phase.PRE_PROTOCOL);
} @Override
public boolean checkUser(String username) {
return ValidUser.validUser.get(username).equals(passwords.get());
} @Override
public void handleMessage(SoapMessage message) throws Fault {
List<Header> headers = message.getHeaders();
if(headers == null || headers.size() == 0)
{
throw new Fault(new RuntimeException("无密码信息"));
} Element passwordEle = null; for(Header header: headers)
{
QName qName = header.getName();
String nameSpace = qName.getNamespaceURI();
String tagName = qName.getLocalPart(); if(nameSpace != null && nameSpace.equals("http://login.check.ws.password") && tagName != null)
{
passwordEle = (Element)header.getObject();
break;
}
} if(null == passwordEle)
{
throw new Fault(new RuntimeException("无密码信息"));
} NodeList passwordList = passwordEle.getElementsByTagName("password"); if(passwordList == null || passwordList.getLength() != 1)
{
throw new Fault(new RuntimeException("密码信息错误"));
} passwords.set(passwordList.item(0).getTextContent());
} }
客户端
首先是生成客户端代码,在此不在赘述,

然后自定义一个拦截器,向soap消息头中写入密码信息,这里密码的获取也用到的ThreadLocal变量,在测试类中将密码存入ThreadLocal变量中,然后在拦截器中就可以获取到密码了。
拦截器代码如下:
package login.check.ws.client; 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; import login.check.ws.test.LoginTest; public class PasswordInterceptor extends AbstractPhaseInterceptor<SoapMessage> { public PasswordInterceptor() {
super(Phase.PREPARE_SEND);
} @Override
public void handleMessage(SoapMessage message) throws Fault {
List<Header> headers = message.getHeaders();
Document doc = DOMUtils.createDocument(); Element passwordNS = doc.createElementNS("http://login.check.ws.password", "loginCheck");
Element password = doc.createElement("password");
password.setTextContent(LoginTest.password.get()); passwordNS.appendChild(password); headers.add(new Header(new QName("loginCheck"), passwordNS));
} }
测试代码如下:

使用了三个拦截器并将密码存入了ThreadLocal中,
测试结果如下:

代码地址:https://files.cnblogs.com/files/liunianfeiyu/logincheckwebservice.rar
webserive学习记录5-拦截器完成登陆校验的更多相关文章
- SpringMVC学习记录(七)--拦截器的使用
SpringMVC的请求如以下这样的图所看到的: 能够看出全部的请求都要通过Dispatherservlet来接收,然后通过Handlermapping来决定使用哪个控制器,再依据ViewResolv ...
- springMVC学习(12)-使用拦截器
一.拦截器配置和测试: 1)定义两个拦截器,(要实现HandlerInterceptor接口) HandlerInterceptor1: package com.cy.interceptor; imp ...
- SSH进阶(2)——用Struts拦截器实现登陆限制
拦截器从字面意思来看就是限制.限制用户訪问某些网页.在Action提出请求之前用拦截器来做权限设置,让符合的用户跳入对应的界面中.近期做的一个商城项目中就用到了自己定义的拦截器,实现了一个简单的ses ...
- struts2使用拦截器完成登陆显示用户信息操作和Struts2的国际化
其实学习框架,就是为了可以很好的很快的完成我们的需求,而学习struts2只是为了替代之前用的servlet这一层,框架使开发更加简单,所以作为一个小菜鸟,特别感谢那些超级无敌变态开发的框架供我们使用 ...
- spring boot 学习(十二)拦截器实现IP黑名单
拦截器实现IP黑名单 前言 最近一直在搞 Hexo+GithubPage 搭建个人博客,所以没怎么进行 SpringBoot 的学习.所以今天就将上次的”?秒防刷新”进行了一番修改.上次是采用注解加拦 ...
- Struts2重新学习之自定义拦截器(判断用户是否是登录状态)
拦截器 一:1:概念:Interceptor拦截器类似于我们学习过的过滤器,是可以再action执行前后执行的代码.是web开发时,常用的技术.比如,权限控制,日志记录. 2:多个拦截器Interce ...
- AngularJs HTTP响应拦截器实现登陆、权限校验
$httpAngularJS 的 $http 服务允许我们通过发送 HTTP 请求方式与后台进行通信.在某些情况下,我们希望可以俘获所有的请求,并且在将其发送到服务端之前进行操作.还有一些情况是,我们 ...
- SpringMVC 学习笔记(六)拦截器
5.1.处理器拦截器简介 Spring Web MVC的处理器拦截器(如无特殊说明,下文所说的拦截器即处理器拦截器) 类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理. ...
- SpringMVC学习08(拦截器)
8.拦截器 概述 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理.开发者可以自己定义一些拦截器来实现特定的功能. 过滤器与拦截器的区别: ...
随机推荐
- http 301 和 302的区别
301 永久重定向 301 重定向是当用户或搜索引擎向网站服务器发出浏览请求时,服务器返回的HTTP数据流中头信息(header)中的状态码的一种,表示本网页永久性转移到另一个地址. 301 重定向是 ...
- C#如何使用VS2010与SQL2008建立链接及初步调用(转)
关于VS2010与SQL2008建立链接及初步调用问题,网上参考的资料很多,我写这个博客,并非是做重复工作,也不是做搬运工.本文将以一种初学者的角度,去完成从数据库建立,到VS2010与SQL中的数据 ...
- osql执行数据库查询命令并保存到txt文件
osql -Usa -P123 -d AppBox -Q "select * from Menus where sortindex > 1000" -o e:\xxx.txt ...
- JSP中的EL (Express Language表达式语言)
EL语言的目的: 用于无java代码的JSP页面 创建el1.jsp,el2.jsp el1.jsp <%@ page language="java" contentType ...
- Angularjs+ThinkPHP3.2.3集成微信分享JS-SDK实践
先来看看微信分享效果: 在没有集成微信分享js-sdk前是这样的:没有摘要,缩略图任意抓取正文图片 在集成微信分享js-sdk后是这样的:标题,摘要,缩略图自定义 一.下载微信SDK开发包 下 ...
- spring eureka required a bean of type 'com.netflix.discovery.DiscoveryClient' that could not be found.
spring在集成第三方过程很容易出现类名相同,且基本作用相同的类.这样给初学者带来一定的困惑. 导致用错类而出现以下问题. required a bean of type 'com.netflix. ...
- Python网络爬虫-requests模块
requests模块 requests模块是python中原生的基于网络请求的模块,其主要作用是用来模拟浏览器发起请求.功能强大,用法简洁高效.在爬虫领域中占据着半壁江山的地位. 如何使用reques ...
- nginx_auto_deny
nginx auto deny 流量/访问限制脚本 https://files.cnblogs.com/files/ligao/nginx_deny_ip.tar.gz
- MySQL MHA环境搭建
MHA功能: 1,从故障的mysql保存二进制日志时间(binlog events);2,识别含有最新更新的slave:3,应用差异的中继日志(relay log)到其他的slave:4,应用从mas ...
- 垃圾收集器之:CMS收集器
HotSpot JVM的并发标记清理收集器(CMS收集器)的主要目标就是:低应用停顿时间.该目标对于大多数交互式应用很重要,比如web应用.在我们看一下有关JVM的参数之前,让我们简要回顾CMS收集器 ...