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 框架时有所帮助。

相关推荐
宦如云2 分钟前
Assembly语言的嵌入式调试
开发语言·后端·golang
日月星辰Ace7 分钟前
SpringBootTest 不能使用构造器注入
java·spring boot
.又是新的一天.14 分钟前
02_MySQL安装及配置
android·数据库·mysql
Gvemis⁹20 分钟前
Scala总结(三)
开发语言·后端·scala
一只小闪闪21 分钟前
langchain4j搭建失物招领系统(五)---实现失物登记功能-大模型流式输出
java·人工智能·后端
SimonKing26 分钟前
Kafka 4.0.0震撼来袭,彻底摒弃Zookeeper
java·后端·架构
Csss26 分钟前
[抖音]用户首页分享链接获取视频数据,可选解析视频文案
后端
星辰瑞云27 分钟前
Scala(2)
开发语言·后端·scala
Java技术小馆27 分钟前
在分布式系统中如何应对网络分区
java·面试·架构
Postkarte不想说话28 分钟前
OpenWRT ubus使用uci修改配置
后端