当前位置: 首页 > article >正文

SpringMVC 拦截器详解与实战

在 SpringMVC 框架中,拦截器(Interceptor)是一种强大的机制,它允许开发者在控制器方法执行前后进行拦截,从而实现诸如用户权限验证、日志记录、性能监控等各种功能。本文将深入探讨 SpringMVC 拦截器的相关知识,并结合实际案例进行讲解。

一、拦截器的基本概念

SpringMVC 的拦截器类似于 Servlet 中的 Filter 过滤器,用于拦截用户的请求并作出相应的处理。拦截器是可插拔式的设计,这意味着我们可以在配置文件中灵活地启用或禁用某个拦截器。

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

  1. 所属技术不同:过滤器属于 Servlet 技术,而拦截器属于 SpringMVC 框架。

  2. 作用范围不同:过滤器可以对所有请求起作用,包括静态资源的请求;拦截器只对访问 controller 层的请求起作用。

  3. 执行顺序不同:过滤器会在请求进入 Tomcat 容器之后但在请求进入 Servlet 之前执行;拦截器则在请求进入 Servlet 之后和 Controller 控制器之间执行。

三、拦截器的方法

拦截器的核心接口是 HandlerInterceptor,它定义了三个重要的方法:

  1. preHandle 方法:该方法在控制器方法执行之前执行。返回值为 Boolean 类型,如果返回 false,表示拦截,不再向下执行;如果返回 true,表示放行,程序将继续执行控制器中的方法。此方法可用于对请求进行预处理,如判断用户是否登录、是否有权限访问等。

  2. postHandle 方法:该方法在控制器方法执行之后、返回 ModelAndView 之前执行。由于该方法会在 DispatcherServlet 进行视图渲染之前被调用,所以可以用于处理返回的视图,如修改模型和视图中的数据。

  3. afterCompletion 方法:该方法在控制器方法执行完毕之后执行。由于是在 Controller 方法执行完毕之后执行该方法,所以该方法适合进行一些资源清理、记录日志信息等处理操作。

四、单个拦截器的执行流程

当配置了单个拦截器时,程序首先会执行拦截器类中的 preHandle() 方法。如果该方法返回 true,则程序继续向下执行处理器当中的方法;否则不再向下执行。业务处理器(即控制器 Controller 类)处理完请求后,会执行 postHandle() 方法,然后通过 DispatcherServlet 向前端返回响应。在 DispatcherServlet 处理完请求后,才会执行 afterCompletion() 方法。

五、使用拦截器实现用户登录权限验证

下面通过一个实际案例来演示如何使用拦截器实现用户登录权限验证。

1. 登录控制器(LoginController)

@Controller
@RequestMapping("/login")
public class LoginController {

    @RequestMapping(value = "/tologin", method = RequestMethod.GET)
    public String toLogin() {
        return "login";
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(String username, String password, HttpSession session) {
        if (username.equals("admin") && password.equals("123456")) {
            System.out.println("登陆成功");
            session.setAttribute("username", "password");
            return "A";
        }
        return "B";
    }
}

2. 登录页面(login.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<form action="/10SpringMVC/login/login" method="post">
    账户:<input type="text" name="username"/><br/>
    密码:<input type="password" name="password"/><br/>
    <input type="submit" value="登录"/>
</form>
</body>
</html>

预览

3. 拦截器配置

在 springMV.xml 文件中配置拦截器:

xml复制

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/> <!--/**表示所有url-->
        <bean class="com.qcby.config.LoginInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

4. 登录拦截器(LoginInterceptor)

java复制

public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String url = request.getRequestURI();
        if (url.contains("login")) {
            return true;
        } else {
            if (request.getSession().getAttribute("username") != null) {
                return true;
            } else {
                response.sendRedirect("/html/login.html");
                return false;
            }
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

六、多个拦截器的执行流程

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

假设有两个拦截器 Interceptor1 和 Interceptor2,并且在配置文件中,Interceptor1 拦截器配置在前:

xml复制

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.qcby.Interceptor.Interceptor1"/>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.qcby.Interceptor.Interceptor2"/>
    </mvc:interceptor>
</mvc:interceptors>

在这种情况下,preHandle() 方法的执行顺序是 Interceptor1 的 preHandle() 先执行,然后是 Interceptor2 的 preHandle()。而 postHandle() 和 afterCompletion() 方法的执行顺序则相反,即先执行 Interceptor2 的 postHandle() 和 afterCompletion(),再执行 Interceptor1 的 postHandle() 和 afterCompletion()。

七、总结

SpringMVC 拦截器是一种非常实用的机制,通过它可以灵活地对请求进行拦截和处理。在实际开发中,我们可以通过拦截器实现用户权限验证、日志记录、性能监控等多种功能。本文通过详细讲解拦截器的基本概念、方法、执行流程以及实际案例,帮助读者深入理解 SpringMVC 拦截器的使用方法和应用场景。希望本文对大家在学习和使用 SpringMVC 框架时有所帮助。


http://www.kler.cn/a/612326.html

相关文章:

  • GAUSSDB 分布式存储机制深度解析
  • sortablejs el-table 树结构拖拽
  • PHP中yield关键字的使用
  • RestTemplate远程调用接口方式
  • 什么是视图,数据库的视图本质上就是个提前写好的sql语句,创建的一个虚拟表
  • C语言中把函数声明为inline是什么意思?
  • Nginx RTMP 处理模块 (ngx_rtmp_handler.c) 详细分析
  • Go语言分布式锁实战:dlock助力构建高并发稳定系统
  • 工作流引擎Flowable介绍及SpringBoot整合使用实例
  • ubuntu服务器server版安装,ssh远程连接xmanager管理,改ip网络连接。图文教程
  • 什么是 Promise?
  • 在鸿蒙 ArkUI 中使用本地数据缓存
  • 【数学建模】(启发式算法)蚁群算法(Ant Colony Optimization)的详解与应用
  • 深入理解椭圆曲线密码学(ECC)与区块链加密
  • 蓝桥杯模拟题--约数的个数(约数和质因数的区别)
  • spring-ai ollama小试牛刀
  • DaemonSet 与 Deployment 的主要区别
  • VSCode 抽风之 两个conda环境同时在被激活
  • 数字图像处理 -- 霍夫曼编码(无损压缩)练习
  • 解决electron-builder vue 打包后element-ui字体图标不显示问题