Spring MVC中的拦截器

news2024/11/16 13:40:21

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


2.springmvc.xml中注册拦截器

   

<!--注册拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/login.action"/>
            <bean id="myInterceptor" class="com.msb.interceptor.MyInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>


拦截器内容详解


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<String, Object> 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);
    }

多个拦截器执行顺序

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

<!--注册拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/login.action"/>
            <bean id="myInterceptor1" class="com.msb.interceptor.MyInterceptor"></bean>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/login.action"/>
            <bean id="myInterceptor2" class="com.msb.interceptor.MyInterceptor2"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

执行结果: 

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/55762.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java项目导入IDEA的流程配置及常见问题解决(持续更新中...)

Java项目导入IDEA的流程配置及常见问题解决 本文主要演示一个普通 java 项目导入IDEA的流程步骤及可能出现的问题、原因及解决办法。 本文使用的部分软件版本如下&#xff1a; IDEA 2018.3 JDK 1.8 Windows 1.导入Java Priject 导入之后可能发出现大面积红色&#xff0c;这…

StringTable

文章目录1. String的基本特性2. String的内存分配3. String的基本操作4.字符串的拼接操作5. intern()的使用6. G1中的String去重操作1. String的基本特性 2. String的内存分配 使用String的intern方法可以把字符串加入到字符串常量池。同时可以使用该方法来证明JDK8中字符串常量…

PL7022/PL7022B原厂双节/两节锂电池串联充电IC和保护IC

双节锂电池串联管理系列选型表&#xff1a; 型号 封装 功能 PL7022B SOT23-6 双节4.2V锂电池串联保护电路 PL7022 SOT23-6 双节4.35V锂电池串联保护电路 PL7501C ESOP8 升压型双节锂电池串联充电电路&#xff08;VIN:5V&#xff09; PL7222 ESOP8 降压型双节锂电…

ABC 分析法(帕累托分析法、2/8分析法)

在任何特定群体中&#xff0c;重要的因子通常只占少数&#xff0c;而不重要的因子则占多数&#xff0c;因此只要能控制具有重要性的少数因子即能控制全局。例如&#xff0c;在企业中&#xff0c;通常认为它80%的利润来自于20%的项目或重要客户&#xff1b;全球最富有的 20% 人口…

帮公司面试了一个33岁的程序员,只因这一个细节,被我一眼看穿是培训班出来的,没啥工作经验...

首先&#xff0c;我说一句&#xff1a;培训出来的&#xff0c;优秀学员大有人在&#xff0c;我不希望因为带着培训的标签而无法达到用人单位和候选人的双向匹配&#xff0c;是非常遗憾的事情。 最近&#xff0c;在网上看到这样一个留言&#xff0c;引发了程序员这个圈子不少的…

基于功能安全的车载计算平台开发:硬件层面

作为车载智能计算平台功能软件与系统软件的载体&#xff0c;硬件的失效可能直接导致功能软件输出不可信任的结果&#xff0c;从而违背安全目标。由于硬件故障在硬件生命周期中发生时间的随机性&#xff0c;在通过改善流程降低系统性失效的同时&#xff0c;ISO 26262功能安全标准…

Mysql的时间类型选定:Datetime,Timestamp,Bigint

1. 基本区别: 2. 其他特性: 1. TIMESTAMP是以utc格式存储,会自动检索当前时区对时间进行转换,而DATETIME不会。 2. 存入null时,TIMESTAMP会自动存储当前时间,而DATETIME存储null值。 3. 时间计算: DATETIME翻译为汉语即"时间戳",它是当前时间到 Unix元年(1…

RabbitMQ_消息的TTL与死信队列

什么是消息的TTL? TTL time to live&#xff0c;消息的TTL 消息的存活时间或过期时间 什么是死信队列&#xff1f; 当队列中的消息到达存活时间或过期时间后&#xff0c;若未设置死信队列&#xff0c;则该消息将被抛弃&#xff0c;反之则转入死信队列 死信队列 配置类 死…

Polygon zkEVM R1CS与Plonk电路转换

1. 引言 前序博客有&#xff1a; Polygon zkEVM的pil-stark Fibonacci状态机初体验Polygon zkEVM的pil-stark Fibonacci状态机代码解析rank-1 constraint system R1CS 由上图可知&#xff0c;zkEVM会借助SNARK来“验证&#xff08;&#xff08;验证STARK证明&#xff09;的SN…

博安生物再次冲刺港交所上市:负债规模高企,持续出现亏损

11月30日&#xff0c;山东博安生物技术股份有限公司&#xff08;下称“博安生物”&#xff09;再次向港交所递交招股书&#xff0c;准备在港交所主板上市。据贝多财经了解&#xff0c;博安生物曾于2022年5月13日递表&#xff0c;现已“失效”。 相较于此前招股书&#xff0c;博…

【图像分割】基于神经气体网络的图像分割与量化(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

了解抖音小程序的评级。为什么我的抖音小程序申请不了某个功能?

目录前言评级评级运营规范评级周期查看评级评级对应的权益小程序评级审核驳回场景信用分常见问题为什么我的小程序不能挂载短视频&#xff1f;前言 小程序评级体系是衡量小程序整体质量的参照&#xff0c;也是小程序获取对应权益的指南&#xff0c;旨在推动、鼓励开发者提升小…

matlab如何从信号中去除60 Hz Hum电源线噪声

美国和其他几个国家的交流电流以60赫兹的频率振荡。这些振荡经常会破坏测量值并且必须减去。 最近我们被客户要求撰写关于信号去噪数据的研究报告&#xff0c;包括一些图形和统计输出。 在存在60 Hz电源线噪声的情况下研究模拟仪器输入端的开环电压。电压以1 kHz采样。 lo…

C/C++内存管理(malloc/calloc/realloc/free/new/delete/operator new/operator delete)

目录 C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free C内存管理方式:new/delete operator new与operator delete函数 new和delete的实现原理 malloc/free和new/delete的区别 (用法上和底层) 内存泄漏 C/C中程序内存区域划分&#xff1a; 1. 栈又叫堆栈…

Linux C简单服务器模型解析及完整代码

Linux C简单服务器模型解析及完整代码1.服务器端流程及解析2.服务器端代码3.客户端流程及解析4.客户端代码5.不足之处&#xff08;注&#xff1a;流程解析可结合相应代码处一起理解&#xff09;1.服务器端流程及解析 服务器端做的事情&#xff1a; 1.创建监听的套接字。 int s…

JAVA培训之数据库表关联关系

数据库表的关联关系有如下三种&#xff1a; 一对多 一对一 多对多 一对多的关系比较常见&#xff0c;我们在之前练习的都是一对多的关系操作&#xff0c;因此这里就不再重复介绍了。 1.一对一关系 在现实生活中&#xff0c;丈夫与妻子之间的关系就是一对一的关系&…

参数估计(1)-参数的点估计

为了考察总体X 的分布&#xff0c;我们将在2.4 节给出经验分布函数&#xff0c;并在总体X为连续型情形下绘制了频率直方图从中可大致看出总体的分布情况或分布形式&#xff0c;但总体分布中包含的参数往往不知&#xff0e;如何根据抽样对未知参数进行估计&#xff0c;就是本章讨…

pandas分组与聚合groupby()函数详解

一、groupby分组与聚合 分组与聚合通常是分析数据的一种方式&#xff0c;通常与一些统计函数一起使用&#xff0c;查看数据的分组情况 DataFrame.groupby(byNone, axis0, levelNone, as_indexTrue, sortTrue, group_keys_NoDefault.no_default, squeeze_NoDefault.no_default…

基于docker部署实现接口自动化持续集成

01 jenkins介绍及docker部署 Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件项目可以进行持续集成 1、创建网络 2、下载并运行 docker:dind镜像…

思科路由器地址转换配置

思科路由器地址转换1.端口复用(PAT)2.配置PAT1.端口复用(PAT) 复用地址转换也称为端口地址转换&#xff08;Port Address Translation&#xff0c;PAT&#xff09;&#xff0c;首先是一种动态地址转换。路由器将通过记录地址、应用程序端口等唯一标识一个转换。通过这种转换&am…