Java 拦截器深入了解学习

news2025/1/17 4:09:14

Java 拦截器深入了解学习

在这里插入图片描述

命运总是不如愿。 但往往是在无数的痛苦中,在重重的矛盾和艰难中,才使人成熟起来,坚强起来;虽然这些东西在实际感受中给人带来的并不都是欢乐。
————路遥《平凡的世界》

什么是拦截器(Interceptor)

在Spring Boot中,拦截器(Interceptor)是一种用于处理HTTP请求的机制,主要用于执行一些预处理或后处理的逻辑。与AOP不同,拦截器更专注于HTTP请求的处理,而不是面向方法调用等更细粒度的横切关注点。以下是Spring Boot拦截器的详细解释:

1. 拦截器接口:

在Spring Boot中,拦截器需要实现HandlerInterceptor接口。这个接口定义了三个主要的方法:

  • preHandle: 在请求处理之前被调用,用于进行一些预处理操作。
  • postHandle: 在请求处理之后、视图渲染之前被调用,用于进行一些后处理操作。
  • afterCompletion: 在整个请求处理完成后被调用,用于进行一些资源清理操作。

2. 配置拦截器:

在Spring Boot中配置拦截器主要通过实现WebMvcConfigurer接口,并覆盖addInterceptors方法。下面是一个简单的例子:

@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/api/**")  // 拦截的路径
                .excludePathPatterns("/public/**");  // 排除的路径
    }
}

在上述例子中,MyInterceptor 是实现了HandlerInterceptor接口的拦截器类。通过addPathPatterns指定需要拦截的路径,通过excludePathPatterns指定排除的路径。

3. 拦截器的实现:

拦截器的实现类需要实现HandlerInterceptor接口,并覆盖其中的方法,如下所示:

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求处理之前执行的逻辑
        return true; // 返回true表示继续执行后续操作,返回false表示中断请求处理
    }

    @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 {
        // 在整个请求处理完成后执行的逻辑,包括视图渲染之后
    }
}

4. 使用场景:

拦截器常用于:

  • 身份验证和权限控制
  • 日志记录
  • 统一异常处理
  • 请求参数处理等

拦截器(Interceptor)和切面(AOP)之间的区别

尽管拦截器(Interceptor)和AOP(面向切面编程)都是用于处理横切关注点的机制,但它们之间存在一些关键的区别。下面是它们之间的主要区别:

1. 关注点:

  • 拦截器: 主要关注HTTP请求的处理,通常用于预处理、后处理、日志记录等与HTTP请求相关的操作。拦截器工作在Controller层之上,能够截获请求的生命周期。

  • AOP: 关注点更广泛,可以应用于方法调用、对象的创建、属性的获取等各个层面。AOP更灵活,可以在更细粒度的操作上进行横切关注点的处理。

2. 作用范围:

  • 拦截器: 主要作用于HTTP请求处理,对Controller层的处理有直接影响。拦截器的作用范围更集中。

  • AOP: 可以作用于整个应用程序的多个模块,跨足多个层次。AOP的作用范围更广泛,不仅限于HTTP请求。

3. 使用场景:

  • 拦截器: 常用于身份验证、权限控制、日志记录等与HTTP请求生命周期相关的场景。

  • AOP: 常用于横切关注点,如日志记录、性能监控、事务管理等。AOP更适合处理那些与业务逻辑解耦的横切关注点。

4. 实现方式:

  • 拦截器: 在Spring Boot中通过实现HandlerInterceptor接口来创建拦截器。

  • AOP: 在Spring中,可以通过配置切面和通知,使用@Aspect注解等方式实现AOP。

5. 粒度:

  • 拦截器: 作用于整个请求处理阶段,较为粗粒度。

  • AOP: 可以根据需要选择切入点,可以是方法调用、对象的创建等,较为细粒度。

6. 依赖:

  • 拦截器: 主要依赖于Spring MVC框架,用于处理HTTP请求。

  • AOP: 可以独立于任何框架使用,不仅限于Spring框架。

综上所述,拦截器和AOP在关注点、作用范围、实现方式等方面存在差异,开发者可以根据具体需求选择合适的机制。通常情况下,如果只涉及HTTP请求处理相关的横切关注点,拦截器是一个较为合适的选择。如果需要更广泛的横切关注点处理,AOP可能更适合。

所以啊,可能很多时候可能AOP用的更多一些,比如若依的日志系统用的就是AOP切面进行实现,再言之,可能拦截器更加适合权限管理

一般可以这样理解,但并不是绝对的。虽然AOP通常被用于实现横切关注点的功能性需求,例如日志、事务、性能监控等,而拦截器则更常用于处理与HTTP请求生命周期相关的事务,如权限控制。

AOP的功能性:

  • 日志记录: 可以通过AOP实现在方法调用前后记录日志。
  • 事务管理: 可以使用AOP确保一组操作在事务的上下文中执行。
  • 性能监控: 可以通过AOP监控方法的执行时间等性能指标。

拦截器更适合权限控制:

  • 身份验证和授权: 拦截器可以用于对HTTP请求进行身份验证和授权,例如检查用户是否具有执行某个操作的权限。
  • 请求预处理: 可以在拦截器中进行请求的预处理,例如解析请求参数、检查请求头等。

虽然上述是一种常见的用法,但并不是绝对的规则。在实际应用中,AOP和拦截器可以灵活结合,根据具体需求进行选择。例如,权限控制可以通过AOP来实现,而拦截器也可以用于实现功能性的需求。

拦截器(Interceptor)的实现

示例一

在Spring Boot中,可以通过实现HandlerInterceptor接口来创建一个拦截器,用于判断请求是否携带了 token。以下是一个简单的例子:

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TokenInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 从请求头中获取 token
        String token = request.getHeader("Authorization");

        // 判断 token 是否存在
        if (token == null || token.isEmpty()) {
            // 如果不存在,返回未授权状态码,并终止请求
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }

        // 如果存在 token,继续处理请求
        return true;
    }
}

在这个例子中,TokenInterceptor 继承了 HandlerInterceptorAdapter 类,重写了 preHandle 方法。在 preHandle 方法中,从请求头中获取了名为 “Authorization” 的 token,然后判断是否存在。如果不存在,返回未授权状态码(SC_UNAUTHORIZED)并终止请求;如果存在,继续处理请求。

接下来,你需要在配置类中注册这个拦截器:

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 WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册拦截器,并设置拦截的路径
        registry.addInterceptor(new TokenInterceptor())
                .addPathPatterns("/api/**"); // 设置需要拦截的路径
    }
}

在这个例子中,WebMvcConfig 类实现了 WebMvcConfigurer 接口,并覆盖了 addInterceptors 方法,用于注册拦截器。在 addInterceptors 方法中,通过 registry.addInterceptor(new TokenInterceptor()) 注册了 TokenInterceptor 拦截器,并使用 .addPathPatterns("/api/**") 指定了需要拦截的路径,可以根据实际需求进行修改。

示例二

我们再升级一下,需求是在请求前鉴权,如果没有携带 token 则返回 401,在请求后判断逻辑错误返回 500,并在请求完成后输出日志。

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TokenInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 从请求头中获取 token
        String token = request.getHeader("Authorization");

        // 判断 token 是否存在
        if (token == null || token.isEmpty()) {
            // 如果不存在,返回未授权状态码并终止请求
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }

        // 在这里可以进行进一步的鉴权逻辑
        // 如果鉴权失败,可以返回 401 并终止请求
        // ...

        return true; // 鉴权通过,继续处理请求
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 请求处理完成后的逻辑
        if (ex != null) {
            // 如果有异常,返回 500 状态码
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            // 这里可以记录日志或进行其他逻辑处理
            System.err.println("Request completed with error: " + ex.getMessage());
        } else {
            // 请求正常完成,可以记录日志或进行其他逻辑处理
            System.out.println("Request completed successfully");
        }
    }
}

在这个示例中,preHandle 方法用于在请求前进行鉴权,如果没有携带 token 则返回 401,如果鉴权失败可以在这里终止请求。afterCompletion 方法用于在请求完成后进行逻辑处理,如果有异常则返回 500 并记录错误日志,否则记录请求正常完成的日志。请根据实际需求进行适当的调整。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1470383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】C++对C语言的关系,拓展及命名空间的使用

文章目录 📝C简述C融合了3种不同的编程方式:C和C语言关系是啥呢?C标准 🌠C应用🌠C语言优点第一个C程序 🌠命名空间🌠命名空间的使用命名空间的定义 🌠怎么使用命名空间中的内容呢&am…

强化学习入门到不想放弃-3

第三节我们主要讲一下SARSA模型 上节课的链接:强化学习入门到不想放弃-2 (qq.com) 有模型的概念:简单理解,上节课我讲的就是有模型,就是可以开上帝视角,知道全局地图 无模型的概念: 打CS,但是看不到地图的情况,全凭自己探索 今天的讲解环境还是和上节课一样,如下…

Movelt使用笔记-Movelt Setup Assistant

目录 Setup Assistant配置1 Start 加载urdf模型3 Virtual joints 虚拟关节5 Robot Poses 机器人位姿7 Passive Joints 被动关节8 Controllers 控制器9 Simulation 仿真10 3D Perception 3D感知11 Author Information 作者信息12 Configuration Files 配置文件启动MoveIt!Setup…

【Python笔记-设计模式】前端控制器模式

一、说明 常作为MVC(Model-View-Controller)模式的一部分,用来处理用户请求并将其分发给相应的处理程序(即路由匹配)。 (一) 解决问题 将请求的处理流程集中管理,统一处理所有的请求 (二) 使用场景 需…

学习或从事鸿蒙开发工作,有学历要求吗?

目前安卓有2,000万的开发者。本科及以上学历占比为35%;iOS有2,400万开发者,本科及以上学历占比为40% 绝大多数的前端开发者都是大专及以下学历,在2023年华为开发者大会上余承东透露华为的开发者目前有200万,但鸿蒙开发者统计的数据…

3.WEB渗透测试-前置基础知识-快速搭建渗透环境(上)

上一个内容:2.WEB渗透测试-前置基础知识-web基础知识和操作系统-CSDN博客 1.安装虚拟机系统 linux Kali官网下载地址: https://www.kali.org/get-kali/#kali-bare-metal Centos官网下载地址: https://www.centos.org/download/ Deepin官网下…

每个学计算机同学都应该有个创业梦

推荐计算机专业必看的两部电影 经典记录片电影《社交网络》推荐理由豆瓣评分电影简介 德国犯罪喜剧《如何在网上卖迷幻药》推荐理由剧情简介 两部电影主角对比 经典记录片电影《社交网络》 纪录扎克伯格,7年时间,从一名大学生摇身变成亿万富翁的故事 推荐…

解读OpenAI Sora文生视频技术原理

OpenAI Sora文生视频(图像看作单帧视频)一放出就炸翻整个AI 圈,也是ChatGPT掀起GenAI热潮时隔一年后,OpenAI再次史诗级的更新。OpenAI 随后公布的技术综述[文献1],难掩其勃勃雄心:视频生成模型作为世界模拟…

Matlab自学笔记二十七:详解格式化文本sprintf各参数设置方法

1.一个程序引例 上篇文章已经介绍了格式化文本的初步应用,程序示例如下: sprintf(|%f\n|%.2f\n|%8.2f,pi*ones(1,3)) 2.格式化操作符各字段的含义解析 格式化操作符可以有六个字段,只有主字符%和转换格式是必需的,其他都是可选…

CSS3中盒子居中

(1)利用定位(子绝父相)、margin-left、和margin-top实现 (2)利用定位(子绝父相)、transfrom属性实现 (3)利用flex布局实现盒子居中

中科大计网学习记录笔记(十五):可靠数据传输的原理

前前言:看过本节的朋友应该都知道本节长度长的吓人,但其实内容含量和之前的差不多,老师在本节课举的例子和解释比较多,所以大家坚持看完是一定可以理解透彻的。本节课大部分是在提出问题和解决问题,先明确出现的问题是…

Ubuntu22.04和Windows10双系统安装

概要 本篇演示Ubuntu22.04和Windows10双系统的安装。先安装Ubuntu22.04,再安装Windows10。 一、说明 1、电脑 笔者的电脑品牌是acer(宏碁/宏基) 电脑开机按F2进入BIOS 电脑开机按F12进入Boot Manager 2、U盘启动盘 需要用到两个U盘启动盘 (1&a…

IO进程线程day7作业

使用消息队列完成两个进程间相互通信 代码&#xff1a; msgsnd.c #include<myhead.h>//定义消息类型 struct msgbuf {long mtype;char mtext[1024]; };//宏表示消息正文大小 #define MSGSIZE sizeof(struct msgbuf)-sizeof(long)int main(int argc, const char *argv[…

【Java程序员面试专栏 数据结构】四 高频面试算法题:哈希表

一轮的算法训练完成后,对相关的题目有了一个初步理解了,接下来进行专题训练,以下这些题目就是汇总的高频题目,一个O(1)查找的利器哈希表,所以放到一篇Blog中集中练习 题目关键字解题思路时间空间两数之和辅助哈希使用map存储出现过的值,key为值大小,value为下标位置,…

C++-带你走进多态(1)

1. 多态的概念 1.1 概念 多态的概念&#xff1a;通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生出不同的状态。 举个栗子&#xff1a;比如买票这个行为&#xff0c;当普通人买票时&#xff0c;是全价买票&am…

Android Gradle 开发与应用 (一) : Gradle基础

1. Gradle是什么 Gradle是一个通用的构建工具&#xff0c;支持诸多主要的 IDE&#xff0c;包括 Android Studio、IntelliJ IDEA、Visual Studio 等 Gradle 的底层实现(核心引擎和框架)其实是用 Java 编写的开发者通常使用 Groovy 或 Kotlin 来编写构建脚本 1.1 那么为什么Gra…

OSCP靶机--AuthBy

OSCP靶机–AuthBy 1.考点 (1. ftp匿名登陆&#xff0c;搜集信息 2.ftp弱密码 3.hash破解【hashcat与john】4.Windows_Server_2008_R2_Enterprise 土豆提权(32bit)) 1.nmap ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.225.46 -sV -sC -p- --min-rate 5000 Startin…

【Django开发】0到1开发美多shop项目:用户登录模块开发。全md文档笔记(附代码 文档)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论django商城项目相关知识。项目利用Django框架开发一套前后端不分离的商城项目&#xff08;4.0版本&#xff09;含代码和文档。功能包括前后端不分离&#xff0c;方便SEO。采用Django Jinja2模板引擎 Vue.js实现前后端…

undo日志详解

一、undo日志介绍 上一节详细的说了redo日志&#xff0c;redo日志的功能就是把增删改操作都记录着&#xff0c;如果断电导致内存中的脏页丢失&#xff0c;可以根据磁盘中的redo日志文件进行恢复。redo日志被设计出来是为了保证数据库的持久性&#xff0c;undo日志设计出来是为…

【Java程序设计】【C00278】基于Springboot的数码论坛管理系统(有论文)

基于Springboot的数码论坛管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的数码论坛系统 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xff1a;在系统首页可以查看首页、…