过滤器和拦截器实现

news2024/11/18 13:56:09

说明:当用户未经登录,直接访问后台网址时,为了避免可以直接访问后台内容,就需要使用过滤器或拦截器将此类请求在服务器响应数据之前做核对,如果未登录,则驳回请求,返回登录页面,如果登录,则放过该请求,允许访问。关于如何判断用户是否登录,参考JWT令牌。

过滤器

过滤器是Tomcat提供的一种对请求作拦截过滤的技术,使用流程如下:

第一步:创建过滤器类

过滤器类需要实现Filter类,实现doFilter()方法,即过滤方法,该方法可实现对设置的访问进行过滤判断,init()服务器启动需要执行代码,destroy()服务器关闭时需要执行代码可根据需求自行覆写。

过滤类上面加的@WebFilter()注解,括号内表明该过滤器类需要过滤的请求路径,有以下三种情况:

/*(所有请求都过滤)

/login(只过滤/login请求)

/login/ *(login路径下的所有请求都过滤)

我这里模拟拦截下/demo02请求,实际开发中的判断会更复杂,需要判断请求是否有token令牌,核对token令牌能否被正确解析

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 过滤器
 */
@WebFilter("/*")
public class MyFilter implements Filter {

    /**
     * 执行过滤方法,每次在拦截范围内的请求都会被执行
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("<<<<<<<<MyFilter过滤器请求开始执行....>>>>>>>>");

        // 如果请求为/demo02,就拦截下来
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

        String requestURL = httpServletRequest.getRequestURL().toString();

        if (requestURL.contains("demo02")){

            return;
        }

        // 手动放行被拦截的所有方法,默认被过滤的请求是都不放行的
        filterChain.doFilter(servletRequest, servletResponse);

        System.out.println("<<<<<<<<MyFilter过滤器响应开始执行...>>>>>>>>");
    }

    /**
     * 初始化方法,服务器启动就会执行,且只执行一次
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("<<<<<<<<服务器启动执行的代码...>>>>>>>>");
    }

    /**
     * 销毁方法,服务器关闭就会执行,且只执行一次
     */
    @Override
    public void destroy() {
        System.out.println("<<<<<<<<服务器关闭执行的代码...>>>>>>>>");
    }
}

controller层代码

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FilterController {

    @RequestMapping("/login")
    public String login(){
        System.out.println("login方法的执行内容...");
        return "login....";
    }

    @RequestMapping("/demo02")
    public String Demo02(){
        System.out.println("demo02方法的执行内容...");
        return "demo02...";
    }
}

第二步:启动类加注解

启动类需要添加@ServletComponentScan注解,表示开启过滤扫码

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan
public class Start {
    public static void main(String[] args) {
        SpringApplication.run(Start.class, args);
    }
}

第三步:启动

服务器启动:init()方法开始执行
在这里插入图片描述


过滤器doFilter()方法开始执行,/login请求未被拦截,访问成功

在这里插入图片描述
在这里插入图片描述


过滤器doFilter()方法开始执行,/demo02被拦截,访问失败

在这里插入图片描述
在这里插入图片描述


服务器关闭,destroy()方法执行

在这里插入图片描述

小结

需要知道的是,过滤器放行后,并不是直接响应数据,而是执行下一个过滤器。当存在多个过滤器时,过滤器doFliter()方法执行的顺序是过滤器类排序的顺序,且为一个嵌套结构,即先执行MyFilter01,MyFilter01里面嵌套执行MyFilter02,而init()、destroy()方法执行的顺序是过滤器类排序的逆序。

在这里插入图片描述
在这里插入图片描述

拦截器

拦截器是SpringMVC提供的一种对请求作拦截过滤的技术,使用流程如下:

第一步:创建拦截类

与过滤器不同的是,该拦截方法是有返回值的,返回值为boolean类型,true表示放行,false表示拦截,另外,拦截器类和拦截器配置类需要加@Component注解,加入到IOC容器中,不然拦截器配置类无法使用拦截器类对象。当然,拦截器不需要给启动类加@ServletComponentScan注解。

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;

/**
 * 拦截器
 */
@Component
public class MyIntercepor01 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("<<<<<<<<MyIntercepor01拦截器请求开始执行....>>>>>>>>");

        // 如果请求为/demo02,就拦截下来
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;

        String requestURL = httpServletRequest.getRequestURL().toString();

        if (requestURL.contains("demo02")){

            return false;
        }

        System.out.println("<<<<<<<<MyIntercepor01拦截器响应开始执行...>>>>>>>>");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("<<<<<<<<MyIntercepor01 postHandle()执行的代码...>>>>>>>>");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("<<<<<<<<MyIntercepor01 afterCompletion()执行的代码...>>>>>>>>");
    }
}

controller层代码

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class InterceporController {

    @RequestMapping("/login")
    public String login(){
        System.out.println("login方法的执行内容...");
        return "login....";
    }

    @RequestMapping("/demo02")
    public String Demo02(){
        System.out.println("demo02方法的执行内容...");
        return "demo02...";
    }

    @RequestMapping("/demo03")
    public String Demo03(){
        System.out.println("demo03方法的执行内容...");
        return "demo03...";
    }
}

第二步:创建配置类

addPathPatterns():设置拦截的请求;

excludePathPatterns():设置排除拦截的请求;

拦截路径设置,有以下四种情况:

在这里插入图片描述

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 拦截器配置类
 */
@Component
public class MyConfig01 implements WebMvcConfigurer {

    @Autowired
    private MyIntercepor01 myIntercepor01;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 拦截所有除login的请求
        registry.addInterceptor(myIntercepor01)
                .addPathPatterns("/**")
                .excludePathPatterns("/login");
    }
}

第三步:启动

输入/login

在这里插入图片描述
在这里插入图片描述


输入/demo02
在这里插入图片描述
在这里插入图片描述


输入demo03

在这里插入图片描述
在这里插入图片描述

小结

如果存在多个拦截器,拦截器的执行顺序,是在拦截器配置类中添加的顺序,且是线性执行的,即先执MyIntercepor02的请求拦截、响应拦截,再执行MyIntercepor01的请求拦截、响应拦截……当所有的拦截器都执行完毕之后,才会放行请求。
在这里插入图片描述
在这里插入图片描述

值得一提的是,拦截器中的postHandle()和afterCompletion()方法的执行顺序,与配置顺序无关。关于这两个方法的作用,参考:http://t.csdn.cn/DktJv

总结

过滤器和拦截器的区别如下:

(1)技术支撑不同:过滤器由Tomcat提供、拦截器由SpringMVC提供;

(2)拦截的范围不同:过滤器处理的是Tomcat上的所有资源,拦截器只处理Spirng环境中的资源;

(3)两者的执行顺序不同:有过滤器,先执行过滤器;过滤器执行完了,再执行拦截器;

(4)具体的执行顺序不同:有多个过滤器,按照文件排序执行(doFliter()方法),为嵌套执行;有多个拦截器,按照配置类中的代码顺序执行,为线性执行;

(5)拦截路径标识稍有不同:拦截器可以设置拦截一级目录,过滤器没有;

因此,在过滤器和拦截器的选择上,应该视实际情况考虑

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

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

相关文章

PyQt5桌面应用开发(20):界面设计结果自动测试(一)

本文目录 PyQt5桌面应用系列PyQt5的测试驱动开发&#xff08;Test-Driven Development&#xff0c;TDD&#xff09;QTestUI动作函数信号测试 最平凡的例子unittest框架总结 PyQt5桌面应用系列 PyQt5桌面应用开发&#xff08;1&#xff09;&#xff1a;需求分析 PyQt5桌面应用开…

【Apache Pinot】简单聊聊前面没讲的 Deep Store 和 Cluster

背景 前面3篇文章讲解了 Pinot 用的最多的几个组件&#xff0c;现在就聊最后剩下的两个&#xff0c;一个是 Cluster&#xff0c;另外一个就是 Deep Store。 Cluster 其实 Cluster 比较简单&#xff0c;就是一个概念的集合&#xff0c;他说有 Server&#xff0c;Broker 和 Co…

代码随想录算法训练营第五十六天 | 力扣 583. 两个字符串的删除操作, 72. 编辑距离

583. 两个字符串的删除操作 题目 583. 两个字符串的删除操作 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 解析 1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义 …

学会这个Python库,做接口测试不是手拿把掐吗?

我们在做接口测试时&#xff0c;大多数返回的都是json属性&#xff0c;我们需要通过接口返回的json提取出来对应的值&#xff0c;然后进行做断言或者提取想要的值供下一个接口进行使用。 但是如果返回的json数据嵌套了很多层&#xff0c;通过查找需要的词&#xff0c;就很不方便…

三、Typora软件的介绍及安装

1、Typora软件的介绍 (1)Typora时一款Markdown编辑器和阅读器。 (2)Typora使用起来十分简洁&#xff0c;十分方便&#xff0c;可用于记录日常的笔记等。 (3)Markdown 是一种轻量级标记语言&#xff0c;它允许人们使用易读易写的纯文本格式编写文档。 2、Typora软件的安装 …

都说未来AI测试辅助自动化测试,难道手工测试真的要被淘汰了吗?

目录 前言 AI测试的迷思 第一个问题&#xff1a;AI辅助测试真的能用吗&#xff1f; 第二个问题&#xff1a;AI辅助测试已经发展到什么程度了&#xff1f; 第三个问题&#xff1a;哪些软件系统能用AI辅助测试&#xff1f; 总结 总结&#xff1a; 前言 近年来&#xff0c;…

FPGA实现简易的自动售货机模型

文章目录 前言一、系统设计1、模块框图2、状态机框图3、RTL视图 二、源码1.蜂鸣器驱动模块2.按键消抖模块3、PWM模块4、sale_goods模块(状态机部分)5、数码管驱动模块6、Sales(顶层模块) 三、效果四、总结五、参考资料 前言 环境&#xff1a; 1、Quartus18.1 2、vscode 3、板子…

华为OD机试 JavaScript 实现【简单密码】【牛客练习题 HJ21】,附详细解题思路

一、题目描述 现在有一种密码变换算法。 九键手机键盘上的数字与字母的对应&#xff1a; 1--1&#xff0c; abc--2, def--3, ghi--4, jkl--5, mno--6, pqrs--7, tuv--8 wxyz--9, 0--0&#xff0c;把密码中出现的小写字母都变成九键键盘对应的数字&#xff0c;如&#xff1a;a …

Python实现面向对象版学员管理系统

如有错误&#xff0c;敬请谅解&#xff01; 此文章仅为本人学习笔记&#xff0c;仅供参考&#xff0c;如有冒犯&#xff0c;请联系作者删除&#xff01;&#xff01; 1.1需求分析 1.1.1使用面向对象编程思想完成学员管理系统的开发&#xff0c;具体如下&#xff1a; 系统要求…

城镇供水产销差问题分析与对策

城镇自来水与其它商品的经营活动一样存在着产销差&#xff0c;产销差的高低&#xff0c;直接影响着供水企业的经济效益。供水企业的经营活动中不单考虑企业的经济效益&#xff0c;还要考虑社会效益。产销差是客观存在的&#xff0c;造成产销差的原因是多样的&#xff0c;复杂的…

初探图神经网络——GNN

title: 图神经网络(GNN) date: tags: 随笔知识点 categories:[学习笔记] 初探图神经网络(GNN) 文章来源&#xff1a;https://distill.pub/2021/gnn-intro/ 前言&#xff1a;说一下为什么要写这篇文章&#xff0c;因为自己最近一直听说“图神经网络”&#xff0c;但是一直不了…

【LeetCode】24.两两交换链表中的节点

24.两两交换链表中的节点&#xff08;中等&#xff09; 方法一&#xff1a;递归 思路 代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), n…

聊一聊mysql的MVC

技术主题 在mysql世纪使用中&#xff0c;经常涉及到MVCC的概念&#xff08;Multi-Vsersion Concurrency Control&#xff09;&#xff0c;即多版本并发控制&#xff0c;一种并发控制方法&#xff0c;根本目的是主为了提升数据库的并发性能。 mvcc为什么产生 数据库最原生的锁…

解开索引迷局:聚簇索引与非聚簇索引的差异大揭秘!

大家好&#xff0c;我是小米&#xff01;今天我们来聊一聊数据库中的索引&#xff0c;具体地说就是聚簇索引和非聚簇索引。这两者在数据库中扮演着重要的角色&#xff0c;对于我们理解数据库的存储和查询机制非常有帮助。下面就让我来给大家详细解释一下它们的区别吧&#xff0…

为不同的调制方案设计一个单载波系统(映射器-信道-去映射器)(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

RPC介绍

RPC介绍 1 介绍1.1 概述1.2 RPC的分裂发展 2 历史发展1969年11月&#xff0c;ARPAnet 开始建立。1974年&#xff1a;Jon Postel 和 Jim White发表了RFC6741975年&#xff1a;RFC684 作为RFC 674 的注释发表&#xff0c;对RFC 674 的争议进行回复。1976年&#xff1a;RFC 707 发…

C++学习之旅 -类和对象(重点)

文章目录 封装封装的意义案例1案例2 访问权限C中class和struct的区别成员属性私有化构造函数和析构函数构造函数析构函数构造函数的分类以及调用构造&调用 拷贝构造函数调用时机深拷贝&浅拷贝初始化列表类对象作为类成员静态成员C对象模型&this指针成员变量和成员函…

Mybatis Generator源码修改

文章目录 报java.net.MalformedURLException错误解决问题原因&#xff1a;编译的时候没有把下面的dtd文件打进去解决方法 XML文件判空优化-增加空字符串修改InsertSelectiveElementGenerator修改UpdateByPrimaryKeySelectiveElementGenerator XML文件判空优化-最佳解决方案 报j…

一文详解!接口测试 API 自动化测试框架

目录 前言 框架定位 框架架构图 框架介绍 技术栈 Case 展示 执行展示 框架优势&#xff1a; 前言 接口测试 API 自动化测试框架可以提高测试效率和自动化程度&#xff0c;通常包括 HTTP 客户端、测试数据管理、测试报告生成、测试用例管理和调度等功能。下面是一个常用…

【论文】attention is all you need

重点在第三节 attention is all you need摘要1. 绪论2. 背景3. 模型架构3.1 编码器和解码器堆叠 3.2 注意力3.2.1 缩放点积注意力&#xff08;Scaled Dot-Product Attention&#xff09;3.2.2 多头注意力机制3.2.3 模型中注意力的应用 3.3 职位感知前馈网络&#xff08;Positio…