Spring MVC中的拦截器
创始人
2024-03-13 17:57:06
0次

在之前学习JAVAWEB 的时候,我们学习了过滤器的知识。过滤器的作用是保护请求的服务器资源,在请求资源被执行之前,如果请求地址符合拦截范围,则会先执行过滤器。过滤器的执行时机,是在Servlet之前执行的。但是在使用了SpringMVC后,Servlet只有一个了,也就是DisptcherServlet。那么,如果我们仍然使用过滤器来完成请求的拦截,因为过滤器是在Servlet之前执行的,就会造成,过滤器会拦截DispatcherServlet所有的请求。那么,如果我们有部分请求不想被拦截,怎么办?

拦截器使用


Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。
    要使用Spring MVC中的拦截器,就需要对拦截器类进行定义和配置。通常拦截器类可以通过两种方式来定义。
    1.通过实现HandlerInterceptor接口,或继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来定义。
    2.通过实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类来定义。

 

拦截器和过滤器的区别


       1拦截器SpringMVC的,而过滤器是servlet的。
  2拦截器不依赖与servlet容器,由spring容器初始化,过滤器依赖与servlet容器,由servlet容器初始化。
  3拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  4拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  5在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
       6拦截器可以获取IOC容器中的各个bean,而过滤器就不太方便,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

1.定义一个拦截器

public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {/*在请求到达我们定义的handler之前工作的*/System.out.println("MyInterceptor preHandle");/*返回的是true,代表放行,可以继续到达handler*/return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("MyInterceptor postHandle");/*handler 处理单元返回ModelAndView 时候进行 拦截*/}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {/*页面渲染完毕,但是还没有给浏览器响应数据的时候*/System.out.println("MyInterceptor afterCompletion");}
}


2.springmvc.xml中注册拦截器

   


拦截器内容详解


1、preHandle方法

  • 执行时机:  再进入控制单元方法之前执行
  • 如何调用:  按拦截器定义顺序调用
  • 具体作用:  如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去 进行处理,则返回 true。 如果程序员决定不需要再调用其他的组件去处理请求,则返回 false。
  • 参数详解
  1.   HttpServletRequest arg0,拦截的请求的request对象
  2.     HttpServletResponse arg1, 拦截的请求的response对象
  3.     Object arg2       封存了单元方法对象的HandleMethod对象 

   

 /**** @param request  请求对象* @param response 响应对象* @param handler  目标要调用的Handler* @return 返回true放行,返回false拦截* @throws Exception*/public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {/*在请求到达我们定义的handler之前工作的*/System.out.println("MyInterceptor preHandle");/*设置请求和响应的乱码 *//* request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");*/// 判断是否登录/*User user =(User) request.getSession().getAttribute("user");if(null == user)response.sendRedirect("index.jsp");return false;*/// 用户权限控制return true;}

2、postHandle方法

  • 执行时机: 在进行数据处理和做出响应之间进行这个方法的调用
  • 如何调用  :在拦截器链内所有拦截器返成功调用
  • 具体作用:  在业务处理器处理完请求后,但是 DispatcherServlet 向客户端返回响应前被调用,
  • 在该方法中对用户请求 request域数据进行处理。
  • 参数详解
  1.         HttpServletRequest arg0, 拦截的请求的request对象
  2.         HttpServletResponse arg1, 拦截的请求的response对象
  3.         Object arg2, 封存了单元方法对象的HandleMethod对象
  4.         ModelAndView arg3 封存了单元方法的返回值资源路径和请求转到的Map数据 
/**** @param request* @param response* @param handler* @param modelAndView  controller响应的结果,视图和数据* @throws Exception*/public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("MyInterceptor postHandle");/*控制数据*//*Map map = modelAndView.getModel();String msg = (String)map.get("msg");String newMsg = msg.replaceAll("脏话", "**");map.put("msg", newMsg);*//*控制视图*//*modelAndView.setViewName("/testDemo1.jsp");*/}


3、afterCompletion方法

执行时机:  在进行页面渲染的时候执行

  • 如何调用:  按拦截器定义逆序调用  
  • 具体作用:  在DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。
  • 参数详解
  1.         HttpServletRequest arg0, 拦截的请求的request对象
  2.         HttpServletResponsearg1, 拦截的请求的response对象
  3.         Object arg2, 封存了单元方法对象的HandleMethod对象
  4.         Exception arg3 存储了责任链的异常信息
/*** 无论controller是否出现异常,都会执行的方法*  一般来说都做一些资源释放工作* @param request* @param response* @param handler* @param ex* @throws Exception*/public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {/*页面渲染完毕,但是还没有给浏览器响应数据的时候*/System.out.println("MyInterceptor afterCompletion");System.out.println(ex);}

多个拦截器执行顺序

多个拦截器同时存在时,执行的顺序由配置顺序决定. 先配置谁, 谁就先执行.多个拦截器可以理解为拦截器栈, 先进后出(后进先出), 如图所示:

执行结果: 

MyInterceptor preHandle
MyInterceptor2 preHandle
login.action
MyInterceptor2 postHandle
MyInterceptor postHandle
success.jsp 
MyInterceptor2 afterCompletion
MyInterceptor afterCompletion
 

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...