解锁高级技巧:玩转 Spring MVC 自定义拦截器的神奇世界

简介: 解锁高级技巧:玩转 Spring MVC 自定义拦截器的神奇世界

😀前言

在现代的Web应用开发中,控制请求的流程和管理请求的数据变得至关重要。Spring MVC作为一个强大的框架,为我们提供了许多工具来处理这些挑战。其中,自定义拦截器是一个令人激动的概念,它赋予开发者在请求到达目标方法之前和之后执行自定义逻辑的能力。通过精心设计的拦截器,我们可以轻松地添加身份验证、日志记录、数据处理等功能,从而让我们的应用更加安全、高效和易于维护。

🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉



解锁高级技巧:玩转 Spring MVC 自定义拦截器的神奇世界

🤔什么是拦截器

● 说明

  1. Spring MVC 也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能.
  2. 自定义的拦截器必须实现 HandlerInterceptor 接口

● 自定义拦截器的三个方法

  1. preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求request 进行处理。
  2. postHandle():这个方法在目标方法处理完请求后执行
  3. afterCompletion():这个方法在完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。

😍自定义拦截器执行流程分析图

● 自定义拦截器执行流程说明

  1. 如果 preHandle 方法 返回 false, 则不再执行目标方法, 可以在此指定返回页面
  2. postHandle 在目标方法被执行后执行. 可以在方法中访问到目标方法返回的ModelAndView 对象
  3. 若 preHandle 返回 true, 则 afterCompletion 方法 在渲染视图之后被执行.
  4. 若 preHandle 返回 false, 则 afterCompletion 方法不会被调用
  5. 在配置拦截器时,可以指定该拦截器对哪些请求生效,哪些请求不生效

😁自定义拦截器应用实例

● 应用实例需求

完成一个自定义拦截器,学习一下如何配置拦截器和拦截器的运行流程

创建MyInterceptor01

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

解读

     1. preHandle() 在目标方法执行前被执行

     2. 如果preHandle() 返回false , 不再执行目标方法

     3. 该方法可以获取到request, response, handler

     4. 这里根据业务,可以进行拦截,并指定跳转到哪个页面

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

解读

     1. 在目标方法执行后,会执行postHandle

     2. 该方法可以获取到 目标方法,返回的ModelAndView对象

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception  

解读

     afterCompletion() 在视图渲染后被执行, 这里可以进行资源清理工作

@Component
public class MyInterceptor01 implements HandlerInterceptor {
    /**
     * 解读
     * 1. preHandle() 在目标方法执行前被执行
     * 2. 如果preHandle() 返回false , 不再执行目标方法
     * 3. 该方法可以获取到request, response, handler
     * 4. 这里根据业务,可以进行拦截,并指定跳转到哪个页面
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("--MyInterceptor01--preHandle()---");
    }
    /**
     * 解读
     * 1. 在目标方法执行后,会执行postHandle
     * 2. 该方法可以获取到 目标方法,返回的ModelAndView对象
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("--MyInterceptor01--postHandle()--");
    }
    /**
     * 解读
     * 1. afterCompletion() 在视图渲染后被执行, 这里可以进行资源清理工作
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("--MyInterceptor01--afterCompletion()--");
    }
}

创建FurnHandler类

@Controller
public class FurnHandler {
    @RequestMapping(value = "/hi")
    public String hi(User user) {
        System.out.println("---FurnHandler--hi()---");
        return "success";
    }
    @RequestMapping(value = "/hello")
    public String hello() {
        System.out.println("---FurnHandler--hello()---");
        return "success";
    }
}

在 springDispatcherServlet-servlet.xml 配置拦截器

    <!--配置自定义拦截器-spring配置文件-->
    <mvc:interceptors>
        <!--
        解读
        1. 第一种配置方式
        2. 使用ref 引用到对应的myInterceptor01
        3. 这种方式,会拦截所有的目标方法
        -->
        <!--<ref bean="myInterceptor01"/>-->
        <!--解读
        1. 第二种配置方式
        2. mvc:mapping path="/hi" 指定要拦截的路径
        3. ref bean="myInterceptor01" 指定对哪个拦截器进行配置
        -->
        <!--<mvc:interceptor>-->
        <!--    <mvc:mapping path="/hi"/>-->
        <!--    <ref bean="myInterceptor01"/>-->
        <!--</mvc:interceptor>-->
        <!--解读
        1. 第3种配置方式
        2. mvc:mapping path="/h*" 通配符方式 表示拦截 /h 打头的路径
        3. mvc:exclude-mapping path="/hello" /hello不拦截
        4. ref bean="myInterceptor01" 指定对哪个拦截器配置
        -->
        <mvc:interceptor>
            <mvc:mapping path="/h*"/>
            <mvc:exclude-mapping path="/hello"/>
            <ref bean="myInterceptor01"/>
        </mvc:interceptor>
    </mvc:interceptors>

第一种配置方式

       使用ref 引用到对应的myInterceptor01

       这种方式,会拦截所有的目标方法

第二种配置方式

  •        mvc:mapping path="/hi" 指定要拦截的路径
  •        ref bean="myInterceptor01" 指定对哪个拦截器进行配置
<mvc:interceptor>
            <mvc:mapping path="/hi"/>
            <ref bean="myInterceptor01"/>
</mvc:interceptor>

第3种配置方式

  • mvc:mapping path="/h*" 通配符方式 表示拦截 /h 打头的路径
  • mvc:exclude-mapping path="/hello" /hello不拦截
  • ref bean="myInterceptor01" 指定对哪个拦截器配置
 <mvc:interceptor>
            <mvc:mapping path="/h*"/>
            <mvc:exclude-mapping path="/hello"/>
            <ref bean="myInterceptor01"/>
</mvc:interceptor>

创建interceptor.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试自定义拦截器</title>
</head>
<body>
<h1>测试自定义拦截器</h1>
<a href="<%=request.getContextPath()%>/hi">测试自定义拦截器-hi</a><br><br>
<a href="<%=request.getContextPath()%>/hello">测试自定义拦截器-hello</a><br/><br/>
</body>
</html>

完成测试(页面方式)

浏览器 http://localhost:8080/springmvc/interceptor.jsp

完成测试(Postman 方式)

注意

拦截器需要配置才生效,不配置是不生效的.

如果 preHandler() 方法返回了 false, 就不会执行目标方法(前提是你的目标方法被拦截了), 程序员可以在这里根据业务需要指定跳转页面.

🥰多个拦截器执行流程示意图

代码实现

创建MyInterceptor02

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

配置xml

       1.配置的第二个拦截器

       2.多个拦截器在执行时,是顺序执行

    <!--配置自定义拦截器-spring配置文件-->
    <mvc:interceptors>
        <!--
        解读
        1. 第一种配置方式
        2. 使用ref 引用到对应的myInterceptor01
        3. 这种方式,会拦截所有的目标方法
        -->
        <!--<ref bean="myInterceptor01"/>-->
        <!--解读
        1. 第二种配置方式
        2. mvc:mapping path="/hi" 指定要拦截的路径
        3. ref bean="myInterceptor01" 指定对哪个拦截器进行配置
        -->
<!--        <mvc:interceptor>-->
<!--            <mvc:mapping path="/hi"/>-->
<!--            <ref bean="myInterceptor01"/>-->
<!--        </mvc:interceptor>-->
        <!--解读
        1. 第3种配置方式
        2. mvc:mapping path="/h*" 通配符方式 表示拦截 /h 打头的路径
        3. mvc:exclude-mapping path="/hello" /hello不拦截
        4. ref bean="myInterceptor01" 指定对哪个拦截器配置
        -->
        <mvc:interceptor>
            <mvc:mapping path="/h*"/>
            <mvc:exclude-mapping path="/hello"/>
            <ref bean="myInterceptor01"/>
        </mvc:interceptor>
        <!--解读
        1.配置的第二个拦截器
        2.多个拦截器在执行时,是顺序执行
        -->
        <mvc:interceptor>
            <mvc:mapping path="/h*"/>
            <ref bean="myInterceptor02"/>
        </mvc:interceptor>
    </mvc:interceptors>

完成测试(页面方式)

浏览器 http://localhost:8080/springmvc/interceptor.jsp

完成测试(Post 方式)

注意事项和细节

1.如果第1个拦截器的preHandle()返回false,后面都不在执行

2.如果第2个拦截器的preHandle()返回false,就直接执行第1个拦截器的afterCompletion()方法,如果拦截器更多,规则类似

3.说明:前面说的规则,都是目标方法被拦截的前提

😀扩展需求

需求: 如果用户提交的数据有禁用词(比如 病毒),则,在第 1 个拦截器就返回,不执行 目标方法, 功能效果示意图

创建warning.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>警告</title>
</head>
<body>
<h1>不要乱讲话~</h1>
</body>
</html>

修改MyInterceptor01

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("--MyInterceptor01--preHandle()---");
        //获取到用户提交的关键字
        String keyword = request.getParameter("keyword");
        if("病毒".equals(keyword)) {
            //请求转发到warning
            request.getRequestDispatcher("/WEB-INF/pages/warning.jsp")
                    .forward(request,response);
            return false;
        }
        System.out.println("得到到keyword= "+ keyword);
        return true;
    }

完成测试(使用 Postma)

😄总结

本文深入剖析了Spring MVC中自定义拦截器的核心概念和运作原理。通过详细的代码示例,我们学习了拦截器的三个关键方法:preHandlepostHandleafterCompletion,以及它们在请求流程中的作用。从拦截器的创建、配置到实际应用,我们探讨了多种不同场景下的用法,并通过实例演示了如何拦截请求、进行数据处理、实现条件跳转等功能。

自定义拦截器不仅仅是一种技术手段,更是提升应用质量和开发效率的关键工具。通过合理的拦截器设计,我们可以将横切关注点与核心业务逻辑解耦,使代码更加模块化和可维护。在今天不断演进的Web开发领域,掌握自定义拦截器的知识,将为您的应用带来更多的灵活性和竞争优势。

 

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁

希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻

如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞


目录
相关文章
|
1月前
|
JSON 前端开发 Java
SSM:SpringMVC
本文介绍了SpringMVC的依赖配置、请求参数处理、注解开发、JSON处理、拦截器、文件上传下载以及相关注意事项。首先,需要在`pom.xml`中添加必要的依赖,包括Servlet、JSTL、Spring Web MVC等。接着,在`web.xml`中配置DispatcherServlet,并设置Spring MVC的相关配置,如组件扫描、默认Servlet处理器等。然后,通过`@RequestMapping`等注解处理请求参数,使用`@ResponseBody`返回JSON数据。此外,还介绍了如何创建和配置拦截器、文件上传下载的功能,并强调了JSP文件的放置位置,避免404错误。
|
1月前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
25 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
1月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
53 2
|
2月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
1月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
111 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
2月前
|
XML 缓存 前端开发
springMVC02,restful风格,请求转发和重定向
文章介绍了RESTful风格的基本概念和特点,并展示了如何使用SpringMVC实现RESTful风格的请求处理。同时,文章还讨论了SpringMVC中的请求转发和重定向的实现方式,并通过具体代码示例进行了说明。
springMVC02,restful风格,请求转发和重定向
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
3月前
|
XML JSON 数据库
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
这篇文章详细介绍了RESTful的概念、实现方式,以及如何在SpringMVC中使用HiddenHttpMethodFilter来处理PUT和DELETE请求,并通过具体代码案例分析了RESTful的使用。
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
|
3月前
|
Java 数据安全/隐私保护 Spring
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
|
3月前
|
前端开发 应用服务中间件 数据库
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
这篇文章通过一个具体的项目案例,详细讲解了如何使用SpringMVC、Thymeleaf、Bootstrap以及RESTful风格接口来实现员工信息的增删改查功能。文章提供了项目结构、配置文件、控制器、数据访问对象、实体类和前端页面的完整源码,并展示了实现效果的截图。项目的目的是锻炼使用RESTful风格的接口开发,虽然数据是假数据并未连接数据库,但提供了一个很好的实践机会。文章最后强调了这一章节主要是为了练习RESTful,其他方面暂不考虑。
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查