Spring的过滤器、拦截器、切面区别及案例分析

news2024/9/21 7:34:13

Spring的过滤器、拦截器、切面 三者的区别,以及对应案例分析

在这里插入图片描述

一、三者的实现方式

1.1 过滤器 xxxFilter

过滤器的配置比较简单,直接实现Filter接口即可,也可以通过@WebFilter注解实现对特定URL的拦截,Filter接口中定义了三个方法:

  • init(): 该方法在容器启动初始化过滤器时被调用,它在过滤器的整个生命周期只会被调用一次
  • doFilter(): 容器中的每一次请求都会调用该方法,其中的FilterChain用来调用下一个过滤器
  • destory(): 当容器销毁过滤器实例时调用该方法,在过滤器的整个生命周期也只会被调用一次

1.2 拦截器 xxxInterceptor

拦截器它是链式调用,一个应用中可以同时存在多个拦截器,一个请求也可以触发多个拦截器,而每个拦截器的调用会依据它的声明顺序依次执行。实现HandlerInterceptor接口,该接口定义了三个方法:

  • preHandle(): 这个方法将在请求处理之前调用,如果该方法返回false,将视为当前请求结束;
  • postHandle(): 在Controller中的方法调用之后,DispatcherServlet返回渲染视图之前被调用;
  • afterComplete(): 在整个请求结束之后,DispatcherServlet渲染了对应视图之后执行。

1.3 切面 xxxAspect

切面注解能够在任何不想改原来代码的地方添加处理逻辑,可以根据自定义注解定义切面。

  • @Aspect:定义在切面实现类上的注解
  • @Pointcut:定义切入点
  • @Before:切面方法执行之前的增强
  • @After:切面方法执行之后的增强,不管抛异常还是正常退出都执行的增强
  • @AfterReturning:切面方法执行之后的增强,方法正常退出时执行
  • @AfterThrowing:切面方法执行之后的增强,抛出异常后执行
  • @Around:环绕增强,包围一个连接点的增强,可获取执行前信息,可修改执行后数据

二、三者的区别

过滤器:
无法获取请求要访问的类、方法以及参数;
可以获取原始的Http请求与响应。

拦截器:
可以获取请求访问的类、方法;
但是无法获取请求参数的值。

切面:
可以获取访问的类、方法以及参数值;
无法获取Http原始的请求与响应的对象。

=================== 请求处理顺序 ===================
过滤器 -> 拦截器 -> 切面
=================== 报错处理顺序 ===================
切面 -> @ControllerAdvice -> 拦截器 -> 过滤器

三、三者的实现案例

3.1 过滤器:MyFilter

package com.wyw.learn.namebindingvsaop;

import org.springframework.stereotype.Component;

import javax.servlet.*;
import java.io.IOException;

/**
 * @author name:    silk
 * @version 1.0
 * @description: TODO
 * @date 2024/4/22 20:18
 */
@Component
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        String filterVal = "这是我设置的过滤器参数值";
        servletRequest.setAttribute("myFilterParam", filterVal);
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

3.2 拦截器:MyInterceptor

package com.wyw.learn.namebindingvsaop;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author name:    silk
 * @version 1.0
 * @description: TODO
 * @date 2024/4/22 20:22
 */
@Component
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String interceptorVal = "这是我设置的拦截器参数值";
        request.setAttribute("myInterceptorParam", interceptorVal);
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @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);
    }
}

另外,拦截器需要在配置类中规定拦截哪些路径

package com.wyw.learn.namebindingvsaop;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author name:    silk
 * @version 1.0
 * @description: TODO
 * @date 2024/4/22 21:49
 */
@Configuration   // 配置项
public class MyConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor)
                .addPathPatterns("/**");   // 拦截所有URL;
    }
}

3.3 切面:MyAspect

切面注解:

package com.wyw.learn.namebindingvsaop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AopAnno {
}

切面逻辑:

package com.wyw.learn.namebindingvsaop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @author name:    silk
 * @version 1.0
 * @description: TODO
 * @date 2024/4/22 15:39
 */
@Component
@Aspect
public class MyAspect {

    @Pointcut(value = "@annotation(com.wyw.learn.namebindingvsaop.AopAnno)")
    public void pointCut() {

    }


    @Before("pointCut()")
    public void doProcess(JoinPoint joinPoint) {
        Object obj = joinPoint.getArgs().length == 0 ? null : joinPoint.getArgs()[0];
        if (obj == null) {
            return;
        }
        // 获取request对象,注意这已不是原始的请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String aspectVal = "这是我设置的切面参数值";
        request.setAttribute("myAspectParam", aspectVal);

        // 通过切面给参数属性赋值
        Arrays.stream(obj.getClass().getDeclaredFields()).forEach(field -> {
            field.setAccessible(true);
            if ("description".equals(field.getName())) {
                try {
                    field.set(obj, "这是我给请求参数属性设置的切面参数值");
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

3.4 测试类:MyTestController

package com.wyw.learn.namebindingvsaop;

import com.itheima.reggie.entity.Dish;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author name:    silk
 * @version 1.0
 * @description: TODO
 * @date 2024/4/22 20:35
 */
@RestController
@RequestMapping("/myTest")
public class MyTestController {

    @Autowired
    private HttpServletRequest request;

    @PostMapping("/test")
    @AopAnno
    public void testDemo(@RequestBody Dish dish) {
        Object myFilter = request.getAttribute("myFilterParam");
        Object myInterceptor = request.getAttribute("myInterceptorParam");
        Object myAspect = request.getAttribute("myAspectParam");
        String description = dish.getDescription();
        System.out.println("请求中过滤器参数值是:" + myFilter);
        System.out.println("请求中拦截器参数值是:" + myInterceptor);
        System.out.println("请求中切面参数值是:" + myAspect);
        System.out.println("请求参数的Description属性的参数值是:" + description);
    }
}

3.5 测试结果

在这里插入图片描述

附:

附一篇之前写的博客,分析过滤器和拦截器的

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

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

相关文章

选择ERP系统需要考虑哪些因素 企业ERP系统选型指南

ERP系统是一个复杂的软件系统,中小企业要建成ERP系统首先是要选择一个适合自己的ERP软件。目前市场上的ERP软件品种繁多,功能各异,那么中小企业应如何结合自己的实际情况“量体裁衣”找到最适合自己的ERP软件呢?这是目前中小企业进行ERP选型…

Axure糖尿病健康管理APP原型 (知识科普/病友社区/远程医生会诊/购物商城/血糖监测/饮食监测)

作品概况 页面数量:共 50 页 源文件格式:rp格式,兼容 Axure RP 9/10,非程序软件无源代码 应用领域:医疗健康、慢病管理、糖尿病管理 作品特色 本作品为Axure糖尿病健康管理APP端原型图,设计规范内容清晰…

一款新型的Linux服务器管理工具

最近发现了一款新型的Linux服务器管理工具,名称叫1Panel,本文跟大伙分享一下。 一. 产品介绍 1Panel 是一个开源的 Linux 服务器运维管理面板,具有丰富的功能,可对服务器和容器进行管理。 产品提供简洁直观的We图形界面&#x…

HTML随机点名程序

案例要求 1.点击点名按钮&#xff0c;名字界面随机显示&#xff0c;按钮文字由点名变为停止 2.再次点击点名按钮&#xff0c;显示当前被点名学生姓名&#xff0c;按钮文字由停止变为点名 案例源码 <!DOCTYPE html> <html lang"en"> <head> <m…

数据结构实验(二)

单链表的基本操作 一、总的设计思路(c++实现) 1、首先定义一个包含name、gender、student_number、hobbies的学生信息结构体。 2、接着一一写出:链表初始化(initialize)函数、后插法插入(insert)函数、打印信息(output)函数、对链表结点进行排序(sortList)函数、…

【前后端】django前后端交互

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、django是什么二、django前后端交互指引三、总结 前言 随着开发语言及人工智能工具的普及&#xff0c;使得越来越多的人会主动学习使用一些开发语言&#x…

质量精美的UI设计素材库:3000+图标设计资源免费下载!

作为一名设计师&#xff0c;你的设计灵感来自哪里&#xff1f;想象一下吗&#xff1f;事实上&#xff0c;材料库仍然是大多数设计师必不可少的东西&#xff0c;如果你能更方便地找到他们可用的设计材料&#xff0c;那么在创作中&#xff0c;无疑可以用一半的努力得到两倍的结果…

Qt绘制边框有阴影兼容性问题

在Qt开发过程中&#xff0c;有时候我们要显示一个有阴影的对话框&#xff0c;这时一般采用自定义实现&#xff0c;然而最近在开发时软件时&#xff0c;Win11上显示正常&#xff0c;Win10或其他Win11电脑显示不正常&#xff0c;存在兼容性问题吗&#xff1f; 下面是具体的源码 …

【wsl】安装nvm配置

安装nvm 参考https://github.com/nvm-sh/nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bashexport NVM_DIR"$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

JS数组操作:去重,交集,并集,差集

文章目录 去重并集交集差集 去重 //定义常量 res,值为一个Map对象实例 //返回arr数组过滤后的结果&#xff0c;结果为一个数组 //过滤条件是&#xff0c;如果res中没有某个键&#xff0c;就设置这个键的值为 const res new Map(); const arr [1,1,2,2,3,4,4,5,6,6,6,6,4,3];…

MIGO行项目屏幕增强

MIGO行项目屏幕增强 一、增强描述 由于在事务码MIGO中存在的字段中没有能够满足客户需求的字段&#xff0c;所以需要在事务码MIGO的屏幕中添加一个新的页签用来保存物料凭证中行项目增加的字段。 通过查找BADI的程序ZDEMO_BADI,输入参数MIGO后&#xff0c;得到对应BADI为MB_M…

面试官竟然是个小黑子,问我用过状态机吗

状态机的组成 状态机是一种抽象的数学模型&#xff0c;描述了对象或系统在特定时间点可能处于的各种状态以及状态之间的转换规则。它由一组状态、事件、转移和动作组成&#xff0c;用于模拟对象在不同条件下的行为和状态变化。 状态机包括以下基本组成部分&#xff1a; 状态&…

React首次加载渲染2次的问题

在开发React项目的时候&#xff0c;发现useEffect会调用2次的情况&#xff0c;依赖数组明明没有变化&#xff0c;怎么会调用2次&#xff1f;百思不得其解&#xff0c;依赖没变化的话&#xff0c;那肯定是整个组件重渲染了。 最最简单的代码如下&#xff1a; const container …

微信抽奖活动怎么做_微信抽奖大狂欢

随着科技的飞速发展&#xff0c;微信已经成为我们生活中不可或缺的一部分。它不仅仅是一个简单的通讯工具&#xff0c;更是一个集社交、购物、娱乐等多种功能于一体的平台。今天&#xff0c;我们为大家带来了一场别开生面的微信抽奖活动&#xff0c;让你在享受乐趣的同时&#…

三相电子式电表ADL400储能防逆流含CE/MID认证

安科瑞薛瑶瑶18701709087/17343930412 ADL400 导轨式多功能电能表&#xff0c;是主要针对电力系统&#xff0c;工矿企业&#xff0c;公用设施的电能统计、 管理需求而设计的一款智能仪表&#xff0c;产品具有精度高、体积小、安装方便等优点。集成 常见 电 力参数测量及电能…

解决zabbix中文乱码问题

目录 1、遇到的问题 2、解决方法 第一步&#xff1a;在windows电脑上可以搜索simkai.ttf文件&#xff0c;上传到 /usr/share/zabbix/assets/fonts文件夹 第二步&#xff1a;删除软链接 第三步&#xff1a;创建软链接 第四步:重启服务 3、检查问题是否被解决 1、遇到的问…

Unity的Animator Animation的使用攻略

Animator 动画控制器 Animation 动画 动画片段 .anin 一、创建Animator 创建动画控制器 模型添加Animator组件 把控制器和模型绑定 二、创建动画 进入动画界面 创建动画片段anin 动画窗口分析 制作动画 点击录制&#xff0c; 移动子对象&#xff0c;在视窗 通过移动线来编辑关…

相机标定的原理

1.相机标定资料 这个视频是建议有一定基础的去看&#xff0c;详细介绍了整个标定的过程。 https://www.bilibili.com/video/BV1R7411m7ZQ/?spm_id_from333.337.search-card.all.click&vd_sourcec205d4d10f730a57820343328741984a 这个文章基础一点&#xff0c;可以先看 h…

钻刀无忌,过孔莫愁

高速先生成员--姜杰 钻刀是冷的&#xff0c;单板是冷的&#xff0c;眼见着过孔阻抗居高不下&#xff0c;雷豹的心也越来越冷…… 雷豹最近在研究过孔&#xff0c;少不了先学习相关的理论&#xff1a;过孔作为信号路径上一个重要的阻抗突变点&#xff0c;相对于传输线的特征阻抗…

合约X—314协议系统开发

随着区块链技术的不断发展&#xff0c;越来越多的协议被提出和应用&#xff0c;其中X314协议就是其中之一。该协议旨在通过去中心化、安全性和可扩展性等方面&#xff0c;为区块链应用提供更好的支持。本文将从多个角度对X314协议进行深度解析&#xff0c;探讨其优势和不足&…