SpringBoot(七)Filter的使用

    思考一个问题,服务端对于客户端的请求,真的应该照单全收吗?不是的。比如拿我们之前实现的用户注册功能来看,如果用户的昵称带了一些不友好的字母或汉字,你是给他过滤掉呢还是让他注册呢?毫无疑问,我们需要过滤掉一些不友好的请求。 

    如果你是新手,且没看过我之前的一系列SpringBoot文章,建议至少看一下这一篇:

SpringBoot(四)SpringBoot搭建简单服务端_springboot做成服务_heart荼毒的博客-CSDN博客​​​​​​​

    如果你想从头到尾系统地学习,欢迎关注我的专栏,持续更新:

https://blog.csdn.net/qq_21154101/category_12359403.html

目录

一、过滤器Filter

二、创建Filter

三、SpringBoot使用Filter

1、@WebFilter注解 + @ServletComponentScan注解

2、使用@Component注解

四、实践-敏感字过滤器


一、过滤器Filter

    Filter,过滤器,是在客户端和服务端之间用来过滤一些请求的中间件。它的作用通常包括以下几个方面:

1、Session校验

2、用户权限判断

3、敏感词过滤

4、设置编码等

    过滤器可以有0-多个,如下图所示:

二、创建Filter

    Filter是servlet下的一个接口。创建filter的方法比较简单,实现Filter接口就可以了。通常,我们不需要去修改init和destroy的实现,只需要去重写doFiler的方法就可以:

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

public class TestFilter 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 {
        
    }

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

三、SpringBoot使用Filter

    SpringBoot支持使用Filter,那么如何使用呢?有多种方式,除了狗都不用的配置方式外,在这里介绍两种方式。两种方式各有优缺点,可以根据自己的实际需要去使用。

1、@WebFilter注解 + @ServletComponentScan注解

    第一种方式,是分别在Filter的实现类使用@WebFilter注解(表明该类是一个Filter)并且在Application类添加ServletComponentScan注解(告诉Application去什么路径扫描Filter)。如下所示:

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

@WebFilter(urlPatterns = "/*")
public class TestFilter 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 {
        System.out.println("测试第一个过滤器");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan(basePackages = "com.zhaojun.server.filter")
public class AndroidServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(AndroidServerApplication.class, args);
	}
}

    运行一下项目,访问如下接口试试:

http://localhost:8080/register?name=hhh&phone=19999999999&password=123456

 可以看到,输出了如下日志,说明filter是生效的:

@WebFilter注解 + @ServletComponentScan注解的方式使用Filter,可以指定要拦截的url , 但是不能指定过滤器执行顺序。

2、使用@Component注解

    前面我们也说到了,filter可以有0-多个。在实际的项目中,我们可能有多个过滤器并且多个过滤器可能存在必要的先后顺序。那么,使用上面说到的第一种方式就无法满足我们的诉求。这种场景下,可以使用第二种方式@Component注解。如下:

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

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

@Component
@Order(1)
public class Filter1 implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("第1个过滤器");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

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

@Component
@Order(2)
public class Filter2 implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("第2个过滤器");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

    build一下,还是访问这个接口:

​​​​​​​http://localhost:8080/register?name=hhh&phone=19999999999&password=123456

    可以看到,Filter的执行顺序:

使用@Component注解的方式使用Filter,可以保证执行顺序, 但是过滤器不能指定拦截的url , 只能默认拦截全部。

四、实践-敏感字过滤器

    上面介绍了两种使用过滤器的方法,接下来,我们基于之前写的注册接口,去实现一个敏感字过滤器。当注册接口的请求含有敏感字时拦截该请求,不包含敏感字时放行。在这里,我使用的是第一种方式:

package com.zhaojun.server.filter;

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

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {

    String[] sensitiveWords = {"sb", "2b", "cnm"};

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) servletResponse);
        String uri = request.getRequestURI();
        // 暂时只针对register接口过滤
        if (uri.contains("/register")) {
            String queryString = request.getQueryString();
            System.out.println(queryString);
            // 敏感字过滤校验通过,放行
            if (checkSensitiveWords(queryString)) {
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                // 校验不通过,重定向到fail接口
                wrapper.sendRedirect("/fail");
                System.out.println("敏感词过滤拦截");
            }
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    /**
     * 校验请求参数敏感字是否通过
     *
     * @param queryString 请求参数
     * @return true/false
     */
    private boolean checkSensitiveWords(String queryString) {
        for (int i = 0; i < sensitiveWords.length; i++) {
            if (queryString.contains(sensitiveWords[i])) {
                return false;
            }
        }
        return true;
    }
}

    如果敏感词校验没通过,重定向到的fail接口实现如下:

package com.zhaojun.server.controller;

import com.zhaojun.server.result.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RegisterFailController {
    @RequestMapping("fail")
    public Result registerFail() {
        Result result = new Result();
        result.code = 0;
        result.status = "fail";
        result.msg = "昵称含有敏感字";
        return result;
    }
}

    请求接口试试,注意,这次使用一个包含敏感字的名字:​​​​​​​http://localhost:8080/register?name=2b&phone=19999999999&password=123456​​​​​​​

    可以看到,重定向到fail接口,并且输出了昵称含有敏感字:

    本篇介绍了Filter的作用,在SpringBoot中使用Filter的两种方式,并且介绍了两种方式的优缺点(顺序和指定url)。在最后,基于之前的注册接口,实现了一个简单的敏感字过滤器。如果你觉得这篇文章对你有帮助,欢迎留言或点赞。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTTP 请求走私漏洞(HTTP Request Smuggling)

一、什么是Http 请求走私漏洞&#xff1f; HTTP请求走私漏洞&#xff08;HTTP Request Smuggling&#xff09;是一种安全漏洞&#xff0c;利用了HTTP协议中请求和响应的解析和处理方式的不一致性。攻击者通过构造特定的恶意请求&#xff0c;以欺骗服务器和代理服务器&#xff0…

五、DQL-2.基本查询

一、数据准备 1、删除表employee&#xff1a; drop table employee; 2、创建表emp&#xff1a; 3、添加数据&#xff1a; 4、查看表数据&#xff1a; 【代码】 -- 查询数据--------------------------------------------------------- drop table emp;-- 数据准备-----------…

Ubuntu 的安装及其设置

文章目录 安装 Ubuntu屏幕分辨率设置修改软件源服务器锁屏时间设置设置 dash跨系统拖拽复制文件的设置 安装 Ubuntu 首先安装 VMware 虚拟机&#xff0c;虚拟机的安装比较简单&#xff0c;一步步点击Next即可完成安装。 安装完成后启动虚拟机&#xff0c;点击创建新的虚拟机。…

个人博客系统(二)

该博客系统共有八个页面,即注册页面、登录页面、添加文章页面、修改文章页面、我的博客列表页面、主页、查看文章详情页面、个人中心页面。 1 注册页面 该页面如图所示: 首先,要先判断注册的用户名、密码、确认密码以及验证码是否为空,若有一个为空,点击提交,则会提醒 …

“探索图像处理的奥秘:使用Python和OpenCV进行图像和视频处理“

1、上传图片移除背景后下载。在线抠图软件_图片去除背景 | remove.bg – remove.bg 2、对下载的图片放大2倍。ClipDrop - Image upscaler 3、对放大后的下载照片进行编辑。 4、使用deepfacelive进行换脸。 1&#xff09;将第三步的照片复制到指定文件夹。C:\myApp\deepfakeliv…

MFC第十六天 CFileDialog、CEdit简介、(线程)进程的启动,以及Notepad的开发(托盘技术-->菜单功能)

文章目录 CCommonDialogCFileDialogCEdit托盘技术进程的启动附录1:启动线程方式附录2:MFC对话框的退出过程 CCommonDialog 通用对话框 CCommonDialog 这些对话框类封装 Windows 公共对话框。 它们提供了易于使用的复杂对话框实现。 CFileDialog 提供用于打开或保存文件的标准对…

【前端】自制密码展示隐藏按钮

效果 一、前期准备 使用的图片是iconfront上拿的svg代码环境是Vue2 Element 二、创建组件 showPasswordAndclose <template><span class"show-password-container"><span v-if"chooseType CLOSE" click"changeType"><…

手机图片怎么转pdf格式?这几个图片转换方式了解一下

手机图片怎么转pdf格式&#xff1f;将图片转换为PDF的应用场景非常广泛。例如&#xff0c;你可以将多张照片转换为PDF&#xff0c;然后将其作为一本电子相册保存。你也可以将多张图片转换为PDF&#xff0c;然后将其作为一份报告或文档的附件发送给他人。此外&#xff0c;许多人…

数据结构双向链表,实现增删改查

一、双向链表的描述 在单链表中&#xff0c;查找直接后继结点的执行时间为O(1)&#xff0c;而查找直接前驱的执行时间为O(n)。为克服单链表这种单向性的缺点&#xff0c;可以用双向链表。 在双向链表的结点中有两个指针域&#xff0c;一个指向直接后继&#xff0c;另一个指向直…

Python应用实例(二)数据可视化(二)

数据可视化&#xff08;二&#xff09; 1.随机漫步1.1 创建RandomWalk类1.2 选择方向1.3 绘制随机漫步图1.4 模拟多次随机漫步1.5 设置随机漫步图的样式 1.随机漫步 使用Python来生成随机漫步数据&#xff0c;再使用Matplotlib以引人瞩目的方式将这些数据呈现出来。随机漫步是…

vscode远程连接提示:过程试图写入的管道不存在(删除C:\Users\<用户名>\.ssh\known_hosts然后重新连接)

文章目录 复现过程原因解决方法总结 复现过程 我是在windows上用vscode远程连接到我的ubuntu虚拟机上&#xff0c;后来我的虚拟机出了点问题&#xff0c;我把它回退了&#xff0c;然后再连接就出现了这个问题 原因 本地的known_hosts文件记录服务器信息与现服务器的信息冲突了…

reggie优化06-项目部署

1、部署架构 2、部署环境 3、部署前端 4、部署后端 修改图片位置&#xff0c;并push至仓库

【System Verilog and UVM基础入门17】Using get_next_item()

从小父亲就教育我&#xff0c;做一个对社会有用的人&#xff01; 关于握手协议的文章&#xff0c;网上有很多很多&#xff0c;这篇文章是最原滋原味的介绍&#xff0c;希望可以帮助到有缘人&#xff01; uvm_driver #(REQ,RSP) The base class for drivers that initiate req…

k8s如何访问 pod 元数据

如何访问 pod 元数据 **我们在 pod 中运行容器的时候&#xff0c;是否也会有想要获取当前 pod 的环境信息呢&#xff1f;**咱们写的 yaml 清单写的很简单&#xff0c;实际上部署之后&#xff0c; k8s 会给我们补充在 yaml 清单中没有写的字段&#xff0c;那么我们的 pod 环境信…

Python:基于matplotlib与mayavi的3D可视化(点云+等值面)

文章目录 一、3D可视化常用方法二、三维图像在numpy、cv2、以及tifffile.imread中通道的区别三、项目实战 1、基于matplotlib的3D可视化&#xff08;体素体&#xff09; 2、基于mayavi的3D可视化2.0、mayavi使用指南&#xff08;鼠标&#xff09;2.1、mlab.points3d()参数详解…

青岛大学_王卓老师【数据结构与算法】Week05_10_顺序栈的操作3_学习笔记

本文是个人学习笔记&#xff0c;素材来自青岛大学王卓老师的教学视频。 一方面用于学习记录与分享&#xff0c; 另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。 如有侵权&#xff0c;请留言作删文处理。 课程视频链接&#xff1a; 数据结构与算法基础…

【区块链+体育】“数智化”的杭州亚运会,中创助力区块链技术发展

“智能”&#xff0c;是杭州亚运会的办赛理念之一。除了数字藏品开亚运先河&#xff0c;杭州亚组委充分应用区块链、大数据、人工智能等前沿技术&#xff0c;为观众提供从购票、出行、观赛到住宿、美食和旅游等“一站式”服务。 本次亚运会将全程智能陆续落到了实处&#xff0…

简述直线导轨的预压力

直线导轨的预压力是预先给予钢珠负荷力&#xff0c;通俗来说就是加大钢珠直径&#xff0c;利用钢珠和珠道之间负向间隙给予预压&#xff0c;这个举动可以提高直线滑轨的刚性和消除间隙&#xff0c;值得注意的一点是小规格建议选用轻预压以下的预压&#xff0c;避免因为预压选用…

【Spring Boot】Web开发 — Web开发简介

Web开发简介 首先介绍Spring Boot 提供的Web组件spring-boot-starter-web&#xff0c;然后介绍Controller和RestController注解&#xff0c;以及控制数据返回的ResponseBody注解&#xff0c;最后介绍Web配置&#xff0c;以便让读者对使用Spring Boot开发Web系统有初步的了解。…

C# 动态字典(可以随机实时增删访问,保证先入先出的字典)

如果你有以下需求&#xff1a; 1. 需要对Dictionary进行遍历的同时移除或者添加元素 2. 需要按顺序遍历Dictionary并且保证先入先出 3. 需要即时的获取字典内的元素数量&#xff0c;即时增删 如果你觉得好&#xff0c;请给我的框架点一个免费的star&#xff0c;球球啦 Yueh0607…