首页 > 其他分享 >12、SpringMVC之拦截器

12、SpringMVC之拦截器

时间:2023-11-10 20:34:20浏览次数:40  
标签:12 preHandle 请求 SpringMVC 拦截器 拦截 执行 public

12.1、环境搭建

创建名为spring_mvc_interceptor的新module,过程参考9.1节和9.5节

12.1.1、页面请求示例

image

<a th:href="@{/test/hello}">测试拦截器</a>

12.1.2、控制器方法示例

image

    @RequestMapping("/test/hello")
    public String testHello(){
        return "success";
    }

12.2、拦截器的入门示例

12.2.1、创建拦截器

image

package online.liaojy.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author liaojy
 * @date 2023/11/7 - 20:57
 */
// SpringMVC 中的拦截器要实现 HandlerInterceptor 接口
public class AAAInterceptor implements HandlerInterceptor {

    // preHandle()方法在控制器方法执行之前执行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("AAAInterceptor-->preHandle()");

        // 返回true表示不拦截,即执行控制器方法
        // 返回false表示拦截,即不再执行控制器方法
        return true;
    }

    // postHandle()方法在控制器方法执行之后执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("AAAInterceptor-->postHandle()");
    }

    // afterCompletion()方法在渲染完视图之后执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("AAAInterceptor-->afterCompletion()");
    }

}

12.2.2、配置拦截器

与自定义的过滤器一样,自定义的拦截器也要配置后才能生效;

过滤器是服务器中的组件,所以配置到 web.xml 中;

拦截器是 springmvc 中的组件,因此要配置到 springmvc 的配置文件中。

image

    <mvc:interceptors>
        <bean class="online.liaojy.interceptor.AAAInterceptor"></bean>
    </mvc:interceptors>

12.2.3、测试效果

image

image

因为在配置拦截器时,没有指定要拦截的路径,所以访问任何DispatcherServlet处理的资源时,拦截器都会执行。

image

image

image

12.3、拦截器的注解配置

除了使用 bean 标签通过全限定类名来配置拦截器,还可以通过 ref 标签引用已存在的 bean 组件来配置拦截器

12.3.1、将拦截器标识为bean组件

image

因为拦截器不属于持久层、业务层和控制层,所以应该用 @Component 注解将其标识为一个 bean 组件

@Component

12.3.2、通过ref标签引用配置拦截器

image

    <mvc:interceptors>
        <ref bean="AAAInterceptor"></ref>
    </mvc:interceptors>

12.4、拦截器的进阶示例

通过上述的方式来配置拦截器,会对 DispatcherServlet 所处理的所有请求都进行拦截;

在实际情况中,可能只需要拦截部分请求,或排除部分请求的拦截。

12.4.1、精确的拦截配置

image

    <mvc:interceptors>
        <mvc:interceptor>
            <!--通过mvc:mapping设置要拦截的请求,可以设置多个;用通配符时,/*表示只拦截一级路径的,/**才表示拦截任意的-->
            <mvc:mapping path="/**"/>
            <!--通过mvc:exclude-mapping设置要排除拦截的请求,可以设置多个 -->
            <mvc:exclude-mapping path="/abc"/>
            <!--设置实行精确拦截规则的拦截器-->
            <bean class="online.liaojy.interceptor.AAAInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

12.4.2、测试效果

image

image

如上图所示,拦截了一级路径的请求

image

image

image

如上图所示,拦截了二级路径的请求

image

image

如上图所示,没有拦截/abc的请求

注意:为实现演示效果,本例已在springmvc配置文件中设置了关于/abc请求的视图控制器

<mvc:view-controller path="/abc" view-name="success"></mvc:view-controller>

12.5、多个拦截器的执行顺序

12.5.1、创建另一个拦截器

image

package online.liaojy.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author liaojy
 * @date 2023/11/9 - 7:27
 */
public class BBBInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("BBBInterceptor-->preHandle()");
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("BBBInterceptor-->postHandle()");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("BBBInterceptor-->afterCompletion()");
    }
}

12.5.2、配置多个拦截器

image

    <mvc:interceptors>
        <bean class="online.liaojy.interceptor.AAAInterceptor"></bean>
        <bean class="online.liaojy.interceptor.BBBInterceptor"></bean>
    </mvc:interceptors>

12.5.3、情况一

  • 如果每个拦截器的preHandle()都返回true

  • 此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关

  • preHandle()会按照配置的顺序执行,而postHandle()和afterCompletion()会按照配置的反序执行

image

image

注意:此时 AAAInterceptor 和 BBBInterceptor 拦截器的 preHandle() 方法返回值都是 true

12.5.4、情况二

  • 如果某个拦截器的preHandle()返回了false

  • 返回false的拦截器和它之前的拦截器的preHandle()都会执行

  • 所有postHandle()都不执行

  • 返回false的拦截器之前的拦截器的afterCompletion()会执行

image

image

注意:此时 AAAInterceptor 拦截器的 preHandle() 方法返回值为true,而 BBBInterceptor 拦截器的为 false

12.5.5、执行顺序流程图

image

12.6、相关拓展

12.6.1、拦截器与过滤器的区别

  • 过滤器是 Tomcat 服务器中的对象,拦截器是 SpringMVC 框架中的对象;

  • 过滤器实现的是 Java 中的 Filter 接口,拦截器实现的是 SpringMVC 中的 HandleInterceptor 接口;

  • 过滤器配置在 web.xml 中,拦截器配置在 SpringMVC 配置文件中;

  • 过滤器在拦截器之前执行;

  • 过滤器是一个执行时间点;拦截器是三个执行时间点;

  • 过滤器除了对动态资源进行过滤之外,还可以对静态资源(HTML、CSS、JS、图片等)进行过滤;

  • 拦截器侧重对控制器方法进行拦截处理,如果一个请求不能被DispatcherServlet接收,那这个请求也不会被拦截器处理。

12.6.2、拦截器的应用场景

  • 权限校验:用户在访问某资源时,可以使用拦截器对用户请求进行拦截,
    判断当前用户有没有登录,如果没有登录则强制回到登录页面进行登录。

  • 性能监控:如果想统计用户访问某个控制器方法的时间,可以使用拦截器对控制器方法进行前置拦截和后置拦截,
    在前置拦截器里面记录用户访问资源的起始时间,在后置拦截器里面记录用户访问资源的结束时间,
    两个时间之差就是当前用户访问控制器方法是总时长。

  • 日志记录:记录请求资源的日志信息,比如请求方式、请求参数、请求响应等,都可以通过拦截器来实现信息记录。

标签:12,preHandle,请求,SpringMVC,拦截器,拦截,执行,public
From: https://www.cnblogs.com/Javaer1995/p/17811857.html

相关文章

  • crypto6-12(crypto0)+萌新赛签到题、萌新密码2
    crypto6  U2FsdGVkX1开头可能为rabbit加密,并且密码为Rabbit,直接将文字符号去掉即可crypto7 okok编码直接用brainfuck解密 crypto8 和第七题差不多,同样要使用brainfuck,点击brainfucktotext就可得出答案crypto9 点击文件时发现需要密码,然后用CTF工具中的Advanced......
  • 12个常用的IDEA快捷键
    sout:快速生成System.out.println();psvm:快速生成main方法;Ctrl+Alt+V:补全等号左边的变量类型和变量名;Ctrl+Shift+Enter/ Alt+Enter :补全当前行的结束分号,或者在方法名、if后使用可补全小括号和花括号;Shift+Enter:在当前行的下一行创建新行,相当于光标跳转到......
  • 解决etcd服务--listen-metrics-urls=http://127.0.0.1:2381
     1、查看etcd的2381端口[root@master-nodemanifests]#netstat-anp|grep2381tcp00127.0.0.1:23810.0.0.0:*LISTEN21765/etcd2、获取etcd的pod[root@master-nodemanifests]#kubectlgetpod-ANAMESPACENAME......
  • 已知数组arr = [2,20,3,12,9],现在要对数组进行遍历,只要数组存在大于10的元素,则输出tru
    Avarres=arr.filter((val1,val2)=>{returnval1>10;})console.log(res);Bvarres=arr.some((val1,val2)=>{returnval1>10;})console.log(res);Cvarres=arr.every((val1,val2)=>{returnval1>10;})console.log(res);Dvarres......
  • 【openfeign】OpenFeign的扩展、日志、超时时间、拦截器、客户端组件、压缩
    Feign的日志配置有时候我们遇到Bug,比如接口调用失败、参数没收到等问题,或者想看看调用性能,就需要配置Feign的日志了,以此让Feign把请求信息输出来。全局配置定义一个配置类,指定日志级别:packagecom.morris.user.config;importfeign.Logger;importorg.springframework.context.a......
  • SqlDateTime 溢出。必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM之间
    由于数据库中DateTime类型字段,最小值是1/1/175312:00:00,而.NETFramework中,DateTime类型,最小值是1/1/00010:00:00,显然,超出了sql的值的最小值范围,导致数据溢出错误usingSystem.Data.SqlTypes;namespaceConsoleApplication1{classProgram{staticvoidM......
  • python升级到3.12版本, 开发模式安装包, 在vscode下Pylance无法解析的问题处理
    问题描述在python3.11版本下开发python库,为方便调测,使用开发模式安装包.使用如下命令:pipinstall-e.其中-e参数表示开发模式下安装python包,它并没有把包相关文件拷贝到site-packages目录,而是创建一个链接指向当前的开发库.这样,当自己开发的包修改后会立即生效,......
  • Educational Codeforces Round 126 (Rated for Div. 2)
    https://codeforces.com/contest/1661/B题数据很小,直接bfs预处理就行C题随便猜了一下,设mx=\(max\{a_i\}\)最后的值应该是mx,mx+1,mx+2,mx+3之类的吧D题刚开始从前面考虑,陷入僵局,一度非常的困,学习凯库勒睡了一会,就突然想到了,前面不行,就从后面考虑,可以发现,从后面考虑的话,就非常......
  • 电源集成模块 (PIM) 3 沟道,NXH240B120H3Q1SG和NXH240B120H3Q1PG 1200V IGBT
    NXH240B120H3Q1是一款3沟道1200VIGBT+SiC升压模块。每个沟道由一个快速开关80AIGBT、一个20ASiC二极管、一个旁通二极管和一个IGBT保护二极管组成。该模块具有内置的热敏电阻和压接引脚。IGBT模块:NXH240B120H3Q1SG、NXH240B120H3Q1PG(明佳达电子供求库存)产品描述......
  • 19.12 Boost Asio 获取远程进程
    远程进程遍历功能实现原理与远程目录传输完全一致,唯一的区别在于远程进程枚举中使用EnumProcess函数枚举当前系统下所有活动进程,枚举结束后函数返回一个PROCESSENTRY32类型的容器,其中的每一个成员都是一个进程信息,只需要对该容器进行动态遍历即可得到所有的远程主机列表。服务端......