【Spring底层原理高级进阶】轻松掌握 Spring MVC 的拦截器机制:深入理解 HandlerInterceptor 接口和其实现类的用法

这篇具有很好参考价值的文章主要介绍了【Spring底层原理高级进阶】轻松掌握 Spring MVC 的拦截器机制:深入理解 HandlerInterceptor 接口和其实现类的用法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 🎉🎉欢迎光临🎉🎉

🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀

🌟特别推荐给大家我的最新专栏《Spring 狂野之旅:底层原理高级进阶》 🚀

本专栏纯属为爱发电永久免费!!!

这是苏泽的个人主页可以看到我其他的内容哦👇👇

努力的苏泽http://suzee.blog.csdn.net/

老样子 先用一个生动的例子 来讲解 今天的主角 拦截器的作用

一天,我们的主角坤坤打算开一家篮球店,他兴致勃勃地准备了一切,从篮球装备到装修风格,都精心设计。他决定给自己的篮球店起名叫"坤坤篮球店",希望能够吸引更多的篮球爱好者。

坤坤开业的第一天,篮球店迎来了很多顾客。他兴奋地迎接每个人,向他们介绍店里的产品和服务。然而,坤坤很快发现,有一些顾客可能并不是真正的篮球爱好者,而是想趁机捣乱或者做一些不合法的事情,也就是人们常说的“小黑子”

这时,他决定在篮球店的入口处设置三个聪明又可爱的坤家卫 人称“三只鸡脚”,它是坤坤的得力助手。这个鸡脚像个守门员,聪明地分辨出哪些人是真爱粉,哪些人只是小黑子,并义正言辞的嘲讽那些虚假的粉丝 并给予礼貌的问候“你最好是”。


每当有人进入篮球店,坤家卫会迅速判断他们的目的。如果是真正的篮球爱好者,拦截器会热情地引导他们到合适的偶像练习生区域,给予他们服务。在他们进行愉快的热舞之前,需要将舞台和背景板渲染成他们喜欢的模样。而对于那些可疑的人,拦截器会立即拦截他们,阻止他们进一步的行动。

最后在激情的热舞过后 会有剩余的坤家卫 打扫战场,作后续操作与资源清理

上面那个故事我们可以预见 坤坤篮球店的兴起  这离不开三位坤家卫的协作  既然如此 那么我们也走进SpringMVC的拦截器当中 深入了解其原理与机制

正片

目录

老样子 先用一个生动的例子 来讲解 今天的主角 拦截器的作用

上面那个故事我们可以预见 坤坤篮球店的兴起  这离不开三位坤家卫的协作  既然如此 那么我们也走进SpringMVC的拦截器当中 深入了解其原理与机制

正片

介绍

具体实现:

那么,我们也可以创建一个自己的拦截器 来为业务服务:

在上述示例中,我们通过addInterceptors方法向InterceptorRegistry注册了CustomInterceptor,并使用addPathPatterns方法指定了拦截的URL模式,这里使用"/**"表示拦截所有请求。

拦截器在实际项目中有多种应用场景,除了身份验证之外还有以下常见用途,以及我做过在业务中的具体实现:

一些拦截器的注意事项和最佳实践包括:


介绍

拦截器在 Spring MVC 中扮演着重要的角色,用于拦截请求和响应的处理过程,并允许开发人员在请求进入控制器之前或离开控制器之后执行自定义的逻辑。它提供了一种在请求的不同生命周期阶段插入自定义代码的机制。

与过滤器相比,拦截器更加专注于处理控制器级别的逻辑,它们与控制器紧密耦合,并且可以访问和修改控制器方法的参数和返回值。拦截器通常用于实现一些通用的横切关注点,如身份验证、权限检查、日志记录、性能监测等。

在 Spring MVC 中,拦截器通过实现 HandlerInterceptor 接口来定义。HandlerInterceptor 接口包含了三个核心方法:

  1. preHandle:在请求到达控制器之前被调用。可以用于进行一些前置处理,如身份验证、权限检查等。根据返回结果决定是否继续处理请求。

  2. postHandle:在控制器方法执行完成后,视图渲染之前被调用。可以对模型数据进行进一步的处理或修改

  3. afterCompletion:在整个请求处理完成后被调用。用于进行一些资源清理操作或记录请求处理结果等。

这些方法在拦截器链中按照特定的顺序被调用。在多个拦截器存在的情况下,它们的执行顺序由拦截器的配置顺序决定。拦截器链的执行顺序是先进后出的,即先配置的拦截器最后执行。

通过编写自定义的 HandlerInterceptor 实现类,并将其配置到 Spring MVC 中,开发人员可以灵活地控制请求处理过程中的逻辑。拦截器提供了一种可插拔的机制,使得代码的复用性和可维护性得到提高,并且可以有效地实现横切关注点的功能。

具体实现:

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CustomInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求到达控制器之前被调用
        // 可以进行一些前置处理,如身份验证、权限检查等
        // 返回false将阻止继续处理请求,返回true将允许继续处理请求
        String token = request.getHeader("Authorization");
        if (token == null || !isValidToken(token)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在控制器方法执行完成后,视图渲染之前被调用
        // 可以对模型数据进行进一步的处理或修改
        if (modelAndView != null) {
            modelAndView.addObject("customData", "Additional data");
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在整个请求处理完成后被调用
        // 可以进行一些资源清理操作或记录请求处理结果等
        logRequestCompletion(request, response.getStatus());
    }

    private boolean isValidToken(String token) {
        // 验证token的逻辑
        // 返回true表示token有效,返回false表示token无效
        // 这里只是一个示例,实际业务逻辑需要根据具体需求实现
        return true;
    }

    private void logRequestCompletion(HttpServletRequest request, int status) {
        // 记录请求处理结果的逻辑
        // 这里只是一个示例,实际业务逻辑需要根据具体需求实现
        System.out.println("Request completed - URI: " + request.getRequestURI() + ", Status: " + status);
    }
}

那么,我们也可以创建一个自己的拦截器 来为业务服务:

  1. 创建一个Java类,实现HandlerInterceptor接口。例如,我们可以创建一个名为CustomInterceptor的类:
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class CustomInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 实现preHandle方法,在请求到达控制器之前进行拦截和处理
            // 在这里可以实现需要的业务逻辑,例如身份验证、权限检查等
            // 返回true表示继续处理请求,返回false将阻止继续处理请求
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            // 实现postHandle方法,在控制器方法执行完成后进行拦截和处理
            // 在这里可以对模型数据进行进一步的处理或修改
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            // 实现afterCompletion方法,在整个请求处理完成后进行拦截和处理
            // 在这里可以进行一些资源清理操作或记录请求处理结果等
        }
    }
  2. 在CustomInterceptor类中,您可以根据需要实现preHandle、postHandle和afterCompletion方法来编写具体的业务逻辑。

  3. 注册拦截器到Spring MVC配置中。在Spring MVC的配置文件(如XML配置文件或Java配置类)中,通过配置InterceptorRegistry来注册自定义拦截器。以下是一个示例,假设您正在使用Java配置类:

    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class AppConfig implements WebMvcConfigurer {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 注册自定义拦截器
            registry.addInterceptor(new CustomInterceptor()).addPathPatterns("/**");
        }
    }

    在上述示例中,我们通过addInterceptors方法向InterceptorRegistry注册了CustomInterceptor,并使用addPathPatterns方法指定了拦截的URL模式,这里使用"/**"表示拦截所有请求。

拦截器在实际项目中有多种应用场景,除了身份验证之外还有以下常见用途,以及我做过在业务中的具体实现:

  1. 日志记录:拦截器可以用于记录请求和响应的日志信息,包括请求的URL、参数、处理时间等。这对于跟踪和排查问题、性能优化以及统计分析非常有用。

    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class LoggingInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 记录请求的URL和参数
            String url = request.getRequestURL().toString();
            String queryString = request.getQueryString();
            System.out.println("Request URL: " + url);
            System.out.println("Request Parameters: " + queryString);
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            // 在这里可以对响应数据进行记录或处理
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            // 在这里可以记录请求处理时间等信息
        }
    }
  2. 缓存管理:拦截器可以用于缓存管理,例如在请求到达控制器之前检查缓存中是否存在响应数据,如果存在则直接返回缓存数据,避免重复计算或查询数据库。

    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class CacheInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 检查缓存中是否存在响应数据
            String cacheKey = generateCacheKey(request);
            Object cachedData = getFromCache(cacheKey);
            if (cachedData != null) {
                // 直接返回缓存数据
                writeResponseData(response, cachedData);
                return false; // 终止请求继续处理
            }
            return true;
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            // 在这里可以将响应数据缓存起来
            String cacheKey = generateCacheKey(request);
            Object responseData = extractResponseData(response);
            storeInCache(cacheKey, responseData);
        }
    
        private String generateCacheKey(HttpServletRequest request) {
            // 根据请求的URL、参数等生成唯一的缓存键
            // ...
        }
    
        private Object getFromCache(String cacheKey) {
            // 从缓存中获取数据
            // ...
        }
    
        private void writeResponseData(HttpServletResponse response, Object data) {
            // 将数据写入响应
            // ...
        }
    
        private Object extractResponseData(HttpServletResponse response) {
            // 从响应中提取数据
            // ...
        }
    
        private void storeInCache(String cacheKey, Object data) {
            // 将数据存入缓存
            // ...
        }
    }
  3. 权限控制:除了身份验证,拦截器可以用于实现细粒度的权限控制。在preHandle方法中,可以检查当前用户是否具有访问某个资源或执行某个操作的权限,如果没有权限,则可以返回相应的错误信息或重定向到其他页面。

    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class AuthorizationInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 检查用户权限
            if (!hasPermission(request)) {
                // 没有权限,返回错误信息或重定向到其他页面
                response.sendRedirect("/error/unauthorized");
                return false; // 终止请求继续处理
            }
            return true;
        }
    
        private boolean hasPermission(HttpServletRequest request) {
            // 检查当前用户是否具有访问资源的权限
            // ...
        }
    }
  4. 请求参数解析和预处理:拦截器可以用于解析请求参数,并进行一些预处理操作,例如数据格式转换、参数校验等。这有助于减轻控制器方法的负担,使其更专注于业务逻辑的处理。

    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class RequestProcessingInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 参数解析和预处理
            String param1 = request.getParameter("param1");
            String param2 = request.getParameter("param2");
            // 对参数进行处理或校验
            // ...
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            // 在这里可以对模型数据进行进一步处理或修改
        }
    }
  5. 错误处理:拦截器可以用于全局的错误处理,捕获和处理异常。在afterCompletion方法中,可以对异常进行统一的处理,例如记录日志、发送通知等。

    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class ErrorHandlingInterceptor implements HandlerInterceptor {
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
           // 在这里对异常进行统一处理
            if (ex != null) {
                // 记录日志或发送通知
                System.out.println("Exception occurred: " + ex.getMessage());
            }
        }
    }
    
    

    一些拦截器的注意事项和最佳实践包括:

    1. 尽量保持拦截器的逻辑简单和高效,避免过多的复杂业务处理。过多的业务逻辑应该放在控制器或服务层中处理。

    2. 注意拦截器的执行顺序,特别是在多个拦截器同时工作的情况下。可以使用@Order注解或实现Ordered接口来指定拦截器的执行顺序。

    3. 注意拦截器的性能影响。拦截器是链式调用的,每个拦截器都会对请求进行处理,因此需要谨慎处理拦截器的性能,避免不必要的操作和重复计算。

    4. 异常处理:拦截器应该对异常进行适当的处理和封装,以便能够正确地返回错误信息给客户端或进行统一的异常处理。

 文章来源地址https://www.toymoban.com/news/detail-831216.html

到了这里,关于【Spring底层原理高级进阶】轻松掌握 Spring MVC 的拦截器机制:深入理解 HandlerInterceptor 接口和其实现类的用法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring MVC:拦截器

    在 JavaWeb 中, 过滤器 是 Servlet 技术中最实用的技术,能够管理 Web 服务器的所有 Web 资源,实现信息拦截、权限访问控制、过滤敏感词汇、压缩响应信息等功能。它主要用于对用户请求进行预处理,也可以对 HttpServletResponse 进行后处理。 而 Spring MVC 的 拦截器 类似于过滤器,

    2024年02月08日
    浏览(29)
  • Spring MVC 拦截器

    如何实现session共享问题: 1、session都在内存里面存储的,只要有session对象我都分发出去,让其他应用都可以拿到(同步) 缺点: 只要有session对象都要广播出去,而且用户应用比较多了就会导致服务压力大, 2、使用token,登录完之后给你一个token,然后加密完之后发给服务

    2024年02月15日
    浏览(27)
  • 【Redis实战】有MQ为啥不用?用Redis作消息队列!?Redis作消息队列使用方法及底层原理高级进阶

     🎉🎉欢迎光临🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟特别推荐给大家我的最新专栏 《Redis实战与进阶》 本专栏纯属为爱发电永久免费!!! 这是苏泽的个人主页可以看到我其他的内容哦👇👇 努力的苏泽 http://suzee.blog.csdn.net/ 我们用的是云

    2024年02月20日
    浏览(37)
  • Spring MVC学习之——拦截器

    Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、判断用户是否登录等。 ​ 拦截器依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。 Spring的拦

    2024年01月20日
    浏览(35)
  • Spring MVC学习笔记,包含mvc架构使用,过滤器、拦截器、执行流程等等

    😀😀😀创作不易,各位看官点赞收藏. Spring MVC:Spring MVC是Spring Framework的一部分,是基于java实现的MVC的轻量级Web框架。 官网文档地址:https://docs.spring.io/spring-framework/docs/4.2.4.RELEASE/spring-framework-reference/html/mvc.html 轻量级,简单易学。 高效,基于请求和响应的MVC框架。 与Spri

    2024年02月15日
    浏览(37)
  • Spring MVC拦截器和跨域请求

    SpringMVC的拦截器(Interceptor)也是AOP思想的一种实现方式。它与Servlet的过滤器(Filter)功能类似,主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否登录等功能上。 拦截器和过滤器的区别 拦截器是SpringMVC组件,而过滤器是

    2024年02月16日
    浏览(38)
  • Spring MVC拦截器Interceptor使用(判断用户登录)

    Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。 拦截器可以在进入处理器之前做一些操作,或者在处理器完成后进行操作,甚至是

    2024年02月09日
    浏览(33)
  • SpringMVC-2-Spring MVC拦截器详解:从入门到精通

    能够编写拦截器并配置拦截器 1.1 拦截器概念和作用 拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行 作用: 在指定的方法调用前后执行预先设定的代码 阻止原始方法的执行 总结:增强 核心原理:AOP思想 1.2 拦截器和过滤器的区别

    2024年02月12日
    浏览(35)
  • 学习 [Spring MVC] 的JSR 303和拦截器,提高开发效率

                                                   🎬 艳艳耶✌️ :个人主页                                                  🔥 个人专栏 : 《推荐】Spring与Mybatis集成整合》                                                  ⛺️    生活的理想,不断更

    2024年02月09日
    浏览(35)
  • Spring-MVC使用JSR303及拦截器,增强网络隐私安全

    目录 一、JSR303 ( 1 )  是什么 ( 2 )  作用 ( 3 )  常用注解 ( 4 )  入门使用 二、拦截器 2.1  是什么 2.2  拦截器与过滤器的区别 2.3  应用场景 2.4 基础使用 2.5 用户登录权限控制 给我们带来的收获 JSR 303是Java规范请求(Java Specification Request)的一部分, 它定义了一套标准的Jav

    2024年02月09日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包