SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的

在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式

第一种方式是:

要定义的Interceptor类要实现了Spring 的HandlerInterceptor 接口或者是这个类继承实现了HandlerInterceptor 接口的类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ;

第二种方式是:

实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。

实现HandlerInterceptor接口

HandlerInterceptor 接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。

(1 )preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法,顾名思义,该方法将在请求处理之前进行调用。SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。

(一般用来做登录校验,跟权限的验证)

(2 )postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由preHandle 方法的解释我们知道这个方法包括后面要说到的afterCompletion 方法都只能是在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用。postHandle 方法,顾名思义就是在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作(也就是返回的modelMap)。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行,这和Struts2 里面的Interceptor 的执行过程有点类型。Struts2 里面的Interceptor 的执行过程也是链式的,只是在Struts2 里面需要手动调用ActionInvocation 的invoke 方法来触发对下一个Interceptor 或者是Action 的调用,然后每一个Interceptor 中在invoke 方法调用之前的内容都是按照声明顺序执行的,而invoke 方法之后的内容就是反向的。

3 )afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。

接下来是使用,

第一步要定义Interceptor类:

public class ShopLoginInterceptor extends HandlerInterceptorAdapter{
/*
* 主要做事前拦截,即用户操作发生前,改写preHandle里面的逻辑,进行拦截
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//从session中取出用户信息来
Object userObj = request.getSession().getAttribute("user");
if (userObj != null) {
//若用户信息不为空,则将session里的用户信息转换成PersonInfo实体类对象
PersonInfo user = (PersonInfo) userObj;
//做空值判断,确保userId不为空并且该长号的可用状态为1,并且用户类型为店家(再判断usertype是否为2店家)
if (user != null && user.getUserId() != null
&& user.getUserId() > 0 && user.getEnableStatus() == 1)
//若通过验证则返回true,拦截器返回true之后,用户接下来的操作得以正常执行
return true;
}
//若不满足登录验证,则直接跳转到账号登录页面
PrintWriter out = response.getWriter();
//拼接js代码
out.println("<html>");
out.println("<script>");
out.println("window.open ('" + request.getContextPath()
+ "/local/login?usertype=2','_self')");
out.println("</script>");
out.println("</html>");
return false;
}
}

还有一个Interceptor类:

/**
* 店家管理系统操作验证拦截器
* @author L
*
*/
public class ShopPermissionInterceptor extends HandlerInterceptorAdapter {
/**
* 主要做事前拦截,即用户操作发生前,改写preHandle里的逻辑,进行用户操作权限的拦截
* @param request 请求
* @param response 响应
* @param handler controller
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//从session中获取当前选择的店铺
Shop currentShop = (Shop) request.getSession().getAttribute(
"currentShop");
@SuppressWarnings("unchecked")
//从session中获取当前用户可操作的店铺列表
List<Shop> shopList = (List<Shop>) request.getSession().getAttribute(
"shopList");
//非空判断
if (currentShop != null && shopList != null) {
for (Shop shop : shopList) {
//如果当前店铺在可操作的列表里则返回true,进行接下来的用户操作
if (shop.getShopId() == currentShop.getShopId()) {
return true;
}
}
}
//若不满足拦截器的验证则返回false终止用户操作的执行
return false;
}
}

第二步是配置拦截器:

<!-- 5.权限拦截器 -->
<mvc:interceptors>
<!-- 校验是否已经登录了店家管理系统的拦截器 登陆了才能做对店铺的相关操作,所有相关请求都会被拦截先进入前面定义好的ShopLoginInterceptor类中校验-->
<mvc:interceptor>
<mvc:mapping path="/shopadmin/**" />
<bean id="ShopInterceptor" class="xyspgl.interceptor.ShopLoginInterceptor" />
</mvc:interceptor>
<!-- 校验是否对店铺有操作权限的拦截器 ,用户不能操作不属于自己的店铺-->
<mvc:interceptor>
<mvc:mapping path="/shopadmin/**" />
<!-- shoplist page 排除不需要校验的方法,只有在这两个方法获取完店铺列表后,才存在相关操作权限问题-->
<mvc:exclude-mapping path="/shopadmin/shoplist" />
<mvc:exclude-mapping path="/shopadmin/getshoplist" />
<!-- shopregister page 这三个方法也不需要拦截,就是注册相关的-->
<mvc:exclude-mapping path="/shopadmin/getshopinitinfo" />
<mvc:exclude-mapping path="/shopadmin/registershop" />
<mvc:exclude-mapping path="/shopadmin/shoppoperation" />
<!-- shopmanage page 店铺管理页面的两个方法也不需要拦截,因为这两个方法在调用的时候,并没有
生成currentshop的session,因此对它做拦截是没有意义的,拦截了就进入不了 -->
<mvc:exclude-mapping path="/shopadmin/shopmanagement" />
<mvc:exclude-mapping path="/shopadmin/getshopmanagementinfo" />
<bean id="ShopPermissionInterceptor"
class="xyspgl.interceptor.ShopPermissionInterceptor" />
</mvc:interceptor>
</mvc:interceptors>

当然在controller层等需要你将一些数据set入session中来当做拦截器类中的校验条件

Spring拦截器(学习笔记)的更多相关文章

  1. Spring 源码学习笔记10——Spring AOP

    Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...

  2. Spring 源码学习笔记11——Spring事务

    Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...

  3. SpringMVC—Struts2拦截器学习网址整理

    引自:http://blog.csdn.net/wp1603710463/article/details/49982683 SpringMVC—Struts2拦截器学习网址整理 最近项目中遇到权限相关 ...

  4. Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点

    Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...

  5. Spring拦截器中通过request获取到该请求对应Controller中的method对象

    背景:项目使用Spring 3.1.0.RELEASE,从dao到Controller层全部是基于注解配置.我的需求是想在自定义的Spring拦截器中通过request获取到该请求对应于Control ...

  6. spring拦截器中修改响应消息头

    问题描述 前后端分离的项目,前端使用Vue,后端使用Spring MVC. 显然,需要解决浏览器跨域访问数据限制的问题,在此使用CROS协议解决. 由于该项目我在中期加入的,主要负责集成shiro框架 ...

  7. spring cloud(学习笔记)高可用注册中心(Eureka)的实现(二)

    绪论 前几天我用一种方式实现了spring cloud的高可用,达到两个注册中心,详情见spring cloud(学习笔记)高可用注册中心(Eureka)的实现(一),今天我意外发现,注册中心可以无限 ...

  8. Spring 拦截器实现+后台原理(HandlerInterceptor)

    过滤器跟拦截器的区别 spring mvc的拦截器是只拦截controller而不拦截jsp,html 页面文件的.这就用到过滤器filter了,filter是在servlet前执行的,你也可以理解成 ...

  9. Spring拦截器和过滤器

    什么是拦截器 拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在方法执行之前或之后加入某些操作,其实就是AOP的一种实现策略.它通过动态拦截Action调用的对象,允许开发者 ...

  10. Android安装器学习笔记(一)

    Android安装器学习笔记(一) 一.Android应用的四种安装方式: 1.通过系统应用PackageInstaller.apk进行安装,安装过程中会让用户确认 2.系统程序安装:在开机的时候自动 ...

随机推荐

  1. 用于文本分类的多层注意力模型(Hierachical Attention Nerworks)

    论文来源:Hierarchical Attention Networks for Document Classification 1.概述 文本分类时NLP应用中最基本的任务,从之前的机器学习到现在基 ...

  2. SpringBoot的简单登陆开发例子

    1:这个例子用spirngboot整合mybatis,jdbc等技术开发的 2:步骤 2.1:新建一个工程 主要的两个步骤已经贴图了,第二张图是直接在pom.xml文件中加入依赖 2.2:新建完项目, ...

  3. 【html】使ifram搭建的项目,新页面跳出框架

    方法一: <a href="<?php echo $baseUrl . '#/study/order';?>" target="_parent" ...

  4. ubantu服务器配置ss

    阿里云 ubantu16.0(自带pip) 服务端 $ apt-get install python-pip $ pip install shadowsocks $ vim /etc/shadowso ...

  5. package-info.java的使用

    一.引入 上文中,提到了注解类JyzTargetPackage可以定义为@Target(ElementType.PACKAGE),可是在被注解类里我无论怎么加,编译器都报错,于是引入了package- ...

  6. face detection[Multi-view face detection&& MTCNN]

    因为这两篇论文感觉内容较短,故而合并到一个博文中. Multi-view face detection 本文来自<Multi-view Face Detection Using Deep Con ...

  7. nova系列二:kvm介绍

    一 什么是kvm KVM 全称 Kernel-Based Virtual Machine.也就是说 KVM 是基于 Linux 内核实现的,这就使得linux内核本身就相当于一个Hypervisor. ...

  8. HBase篇(2)-数据模型与操作

    HBase其实就是一个数据库,无非就是存储和增删改查,那我们先从数据模型说起把 这里有一张表,是用关系型数据库的思维画出来的表,这样比较易于理解: 概念 Table(表格) 没啥说的,和关系型数据库一 ...

  9. python--Numpy and Pandas 笔记01

    博客地址:http://www.cnblogs.com/yudanqu/ 1 import numpy as np import pandas as pd from pandas import Ser ...

  10. vuex原理

    Vuex 框架原理与源码分析 vuex状态管理到底是怎样一个原理? 状态管理 Vuex框架原理与源码分析 Vuex实现原理解析 Vue刚出不久,Vuex 就出来了,想请教下Vuex做了什么事情? 个人 ...