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

原文地址:https://www.cnblogs.com/liunianfeiyu/p/8399382.html

时间: 2024-10-08 14:21:32

webserive学习记录5-拦截器完成登陆校验的相关文章

SpringMVC学习记录(七)--拦截器的使用

SpringMVC的请求如下面这种图所示: 可以看出所有的请求都要通过Dispatherservlet来接收,然后通过Handlermapping来决定使用哪个控制器,再根据ViewResolver来决定返回哪个视图.从流程来看,Handlermapping就是我们可以实现拦截器的第一种方法.另外还有一种是实现WebRequestInterceptor接口,或者继承其子类. 一.实现HandlerInterceptor接口 实现HandlerInterceptor接口或者继承HandlerInt

springMVC3学习(七)--Interceptor拦截器

Spring为我们提供了:org.springframework.web.servlet.HandlerInterceptor接口, org.springframework.web.servlet.handler.HandlerInterceptorAdapter适配器, 实现这个接口或继承此类,能够很方便的实现自己的拦截器. 有下面三个方法: Action之前运行 public boolean preHandle(HttpServletRequest request, HttpServletR

springmvc学习笔记(20)-拦截器

springmvc学习笔记(20)-拦截器 springmvc学习笔记20-拦截器 拦截定义 拦截器配置 针对HandlerMapping配置 类似全局的拦截器 拦截测试 拦截器应用实现登陆认证 需求 登陆controller方法 登陆认证拦截实现 本文主要介绍springmvc中的拦截器,包括拦截器定义和的配置,然后演示了一个链式拦截的测试示例,最后通过一个登录认证的例子展示了拦截器的应用 拦截定义 定义拦截器,实现HandlerInterceptor接口.接口中提供三个方法. public

Struts2重新学习之自定义拦截器(判断用户是否是登录状态)

拦截器 一:1:概念:Interceptor拦截器类似于我们学习过的过滤器,是可以再action执行前后执行的代码.是web开发时,常用的技术.比如,权限控制,日志记录. 2:多个拦截器Interceptor连在一起组成了Interceptor栈.拦截器是AOP面向切面编程的一种实现,具有热插拔的效应. 3:Struts2拦截器,每个拦截器类只有一个对象实例,即采用了单利模式.所有引用这个拦截器的action都共享着一拦截器类的实例. 拦截器和过滤器的区别 1:拦截器和过滤器的概念非常类似 2:

springMVC学习(12)-使用拦截器

一.拦截器配置和测试: 1)定义两个拦截器,(要实现HandlerInterceptor接口) HandlerInterceptor1: 1 package com.cy.interceptor; 2 3 import javax.servlet.http.HttpServletRequest; 4 import javax.servlet.http.HttpServletResponse; 5 6 import org.springframework.web.servlet.HandlerIn

Struts2自己定义拦截器实例—登陆权限验证

版本号:struts2.1.6 此实例实现功能:用户须要指定username登陆,登陆成功进入对应页面运行操作,否则返回到登陆页面进行登陆,当直接訪问操作页面(登陆后才干訪问的页面)时则不同意,须返回登陆页面. 代码例如以下: 一.页面 login.jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUB

SpringMVC 登陆拦截器实现登陆控制

思路,先登陆后,将登陆信息存储在session中,然后通过拦截器,对系统中的页面和资源进行访问拦截,同时对于登陆本身相关的页面和资源不拦截. 实现方法: /**  * 登陆拦截器.  *  * @author leizhimin 2014/6/26 16:08  */ public class LoginInterceptor extends HandlerInterceptorAdapter {     private static final String[] IGNORE_URI = {"

struts2综合例子--------拦截器(登陆检查,日志记录),校验validate,

列表Action package he.action; import he.dao.UserDAO; import java.sql.SQLException; import java.util.LinkedList; import java.util.List; public class ListAction { private List<User> users = new LinkedList<User>(); public List<User> getUsers(

AngularJs HTTP响应拦截器实现登陆、权限校验

$httpAngularJS 的 $http 服务允许我们通过发送 HTTP 请求方式与后台进行通信.在某些情况下,我们希望可以俘获所有的请求,并且在将其发送到服务端之前进行操作.还有一些情况是,我们希望俘获响应,并且在完成完成调用之前处理它.一个很好例子就是处理全局 http 异常.拦截器(Interceptors)应运而生.本文将介绍 AngularJS 的拦截器,并且给几个有用的例子. 什么是拦截器? $httpProvider 中有一个 interceptors 数组,而所谓拦截器只是一