我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SpringMVC一步到位精通拦截器

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SpringMVC一步到位精通拦截器

前言

在上一篇文章中讲完了SpringMVC的大部分知识,此篇文章中主要讲解拦截器。上一篇文章?

拦截器的使用是非常普遍的。例如在 OA系统中通过拦截器可以拦截未登录的用户,或者使用它来验证己登录用户是否有相应的操作权限等。SpringMVC 中提供了拦截器功能,通过配置即可对请求进行拦截处理。

拦截器概述

SpringMVC 中的拦截器 (Interceptor)类似于 Servlet 中的过滤器(Filter),它主要用于拦截用户请求并做相应的处理。例如通过拦截器可以进行权限验证、判断用户是否己登录等。

拦截器的定义

要使用SpringMVC中的拦截器,就需要对拦截器类进行定义和配置。通常拦截器类可以通过两种方式来定义:

  • 一种是通过实现 HandlerInterceptor 接口或者继承 HandlerInterceptor 接口的实现类(如 HandlerInterceptorAdapter)来定义。
  • 另一种是通过实现 WebRequestInterceptor 接口或继承 WebRequestInterceptor 接口的实现类来定义。

实现HandlerInterceptor接口的定义方式为例,自定义拦截器类的代码如下所示:

public class UserInterceptor implements HandlerInterceptor {
    public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception {
        System.out.println("UserInterceptor...preHandle");
        //对拦截的请求进行放行处理(true为放行,false为不放行)
        return true;
    }
    public void postHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("UserInterceptor...postHandle");
    }
    public void afterCompletion(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("UserInterceptor...afterCompletion");
    }
}

从上述代码可以看出,自定义的拦截器类实现了 HandlerInterceptor 接口,并实现了接口中的3 个方法。关于这3个方法的具体描述如下:

  • preHandle()方法:该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true 时,表示继续向下执行; 当其返回值为false 时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行等)。
  • postHandle()方法:该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。
  • afterCompletion()方法:该方法在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。

拦截器的配置

要使自定义的拦截器类生效,需要在SpringMVC的配置文件中进行配置,配置代码如下:

<!--配置拦截器-->
    <mvc:interceptors>
        <!--使用bean直接定义在<mvc:interceptor>下面的Interceptor 将拦截所有请求-->
        <bean class="com.hzy.interceptor.UserInterceptor"/>
        <!--拦截器1-->
        <mvc:interceptor>
            <!--配置拦截器作用的路径-->
            <mvc:mapping path="/**"/>
            <!--配置不需要拦截器作用的路径-->
            <mvc:exclude-mapping path=""/>
            <!--定义在<mvc:interceptor>下面,表示对匹配路径的请求才进行拦截-->
            <bean class="com.hzy.interceptor.Interceptor1"/>
        </mvc:interceptor>
        <!--拦截器2-->
        <mvc:interceptor>
            <mvc:mapping path="/hello"/>
            <bean class="com.hzy.interceptor.Interceptor2"/>
        </mvc:interceptor>
            ......
    </mvc:interceptors>

在上述代码中, <mvc:interceptors>元素用于配置一组拦截器,其子元素<bean>中定义的是全局拦截器,它会拦截所有的请求;而<mvc:interceptor>元素中定义的是指定路径的拦截器,它会对指定路径下的请求生效。<mvc:interceptor>元素的子元素<mvc:mapping>用于配置拦截器作用的路径,该路径在其属性 path 中定义。如上述代码中 path 的属性值 “/**”表示拦截所有路径, “/hello”表示拦截所有以“hello”结尾的路径。如果在请求路径中包含不需要拦截的内容,还可以通过 <mvc:exclude-mapping>元素进行配置。

拦截器的执行流程

拦截器的执行是有一定顺序的,该顺序与配置文件中所定义的拦截器的顺序相关。

单个拦截器的执行流程

如果在项目中只定义了一个拦截器,那么该拦截器在程序中的执行流程如下图所示。从中可以看出,程序首先会执行拦截器类中的 preHandle()方法,如果该方法的返回值为 true,则程序就会继续向下执行处理器中的方法,否则将不再向下执行:在业务处理器(即控制器Controller 类)处理完请求后,会执行 postHandle()方法,然后通过 DispatcherServlet 向客户端返回响应;在 DispatcherServlet 处理完请求后,才会执行 afterCompletion()方法。

简单的案例

web.xml中配置SpringMVC的前端过滤器和初始化加载配置文件等信息。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <!--配置前端过滤器-->
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--初始化时加载配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-config.xml</param-value>
        </init-param>
        <!--表示容器在启动时立即加载Servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

在class="lazy" data-src下创建com.hzy.controller包,并在里面创建控制器类HelloController,

@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String hello(){
        System.out.println("Hello");
        return "success";
    }
}

在class="lazy" data-src下创建com.hzy.interceptor包,并在里面创建拦截器类UserInterceptor,该类需要实现HandlerInterceptor接口。

public class UserInterceptor implements HandlerInterceptor {
    public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception {
        System.out.println("UserInterceptor...preHandle");
        //对拦截的请求进行放行处理(true为放行,false为不放行)
        return true;
    }
    public void postHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("UserInterceptor...postHandle");
    }
    public void afterCompletion(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("UserInterceptor...afterCompletion");
    }
}

在resources目录下创建springmvc-config.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--指定需要扫描的包-->
    <context:component-scan base-package="com.hzy.controller"/>
    <!--定义视图解析器-->
    <bean id="internalResourceViewResolve"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--设置前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--设置后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    <mvc:annotation-driven/>
    <!--配置拦截器-->
    <mvc:interceptors>
        <!--使用bean直接定义在<mvc:interceptor>下面的Interceptor 将拦截所有请求-->
        <bean class="com.hzy.interceptor.UserInterceptor"/>
    </mvc:interceptors>
</beans>

在WEB-INF目录下创建一个jsp文件夹,并在里面创建一个页面文件success.jsp,然后在<body>里面显示任意信息。发布并启动项目,访问http://localhost:8080/springMvc_SSM/hello (注意你的访问路径可能和我不一样哦)

结果:

控制台

多个拦截器的执行流程

在大型项目中,通常会定义很多拦截器来实现不同的功能。多个拦截器的执行顺序如图所示。这里假设有两个拦截器 Interceptor1Interceptor2,并且在配置文件中,Interceptor1拦截器配置在前。

从图上可以看出,当有多个拦截器同时工作时,它们的preHandle()方法会按照配置文件中拦截器的配置顺序执行,而它们的postHandle()方法和afterCompletion()方法则会按照配置顺序的反序执行。

下为了验证上述描述,下面就修改上面的代码来演示多个拦截器的执行。

在com.hzy.interceptor包中创建两个拦截器类Interceptor1和Interceptor2。

Interceptor1.java

public class Interceptor1 implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Interceptor1...preHandle");
        return true;
    }
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor1...postHandle");
    }
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("Interceptor1...afterCompletion");
    }
}

Interceptor2.java

public class Interceptor2 implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Interceptor2...preHandle");
        return true;
    }
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor2...postHandle");
    }
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("Interceptor2...afterCompletion");
    }
}

springmvc-config.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--指定需要扫描的包-->
    <context:component-scan base-package="com.hzy.controller"/>
    <!--定义视图解析器-->
    <bean id="internalResourceViewResolve"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--设置前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--设置后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    <mvc:annotation-driven/>
    <!--配置拦截器-->
    <mvc:interceptors>
        <!--使用bean直接定义在<mvc:interceptor>下面的Interceptor 将拦截所有请求-->
        <bean class="com.hzy.interceptor.UserInterceptor"/>
        <!--拦截器1-->
        <mvc:interceptor>
            <!--配置拦截器作用的路径-->
            <mvc:mapping path="/**"/>
            <!--配置不需要拦截器作用的路径-->
<!--            <mvc:exclude-mapping path=""/>-->
            <!--定义在<mvc:interceptor>下面,表示对匹配路径的请求才进行拦截-->
            <bean class="com.hzy.interceptor.Interceptor1"/>
        </mvc:interceptor>
        <!--拦截器2-->
        <mvc:interceptor>
            <mvc:mapping path="/hello"/>
            <bean class="com.hzy.interceptor.Interceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

上述拦截器的配置代码中,第一个拦截器会作用于所有路径下的请求,而第二个拦截器会作用于“/hello”结尾的请求。运行项目得到结果:

页面输出跟前面一样。

控制台输出:

从图中可以看出,程序先执行了前面两个拦截器类中的preHandle()方法,这两个方法的执行顺序与配置文件中定义的顺序相同;然后执行了控制器中类中的hello()方法;最后执行了两个拦截器类中的postHandle()方法和afterCompletion()方法,且这两个方法的执行顺序与配置文件中所定义的拦截器顺序相反。

到此这篇关于SpringMVC一步到位精通拦截器的文章就介绍到这了,更多相关SpringMVC拦截器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SpringMVC一步到位精通拦截器

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SpringMVC一步到位精通拦截器

拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行。本文将详细讲讲SpringMVC中拦截器的概念及入门案例,感兴趣的可以尝试一下
2022-12-23

Spring一步到位精通拦截器

拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行。本文将详细讲讲SpringMVC中拦截器的概念及入门案例,感兴趣的可以尝试一下
2023-01-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录