从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

  • JavaSenior

  • JavaEE

  • JavaWeb

    • 服务器软件

    • 环境管理和配置管理-科普篇
    • Servlet 入门

      • 什么是 Servlet
      • Servlet 入门案例
      • Servlet 生命周期
      • Servlet 中的注解
      • Tomcat 集成 IDEA
      • Servlet 体系结构
      • HTTP 协议基础
      • 深入 request 和 response 对象
      • request 对象基本使用
      • request 其他功能
      • Servlet 实现登录功能
      • HTTP 协议基础-响应
      • Response 对象基本使用
      • response 对象之重定向
      • response 输出字符到浏览器
      • response 输出字节数据
      • 验证码案例
      • ServletContext
      • 文件下载案例
      • Cookie 笔记
      • Cookie 的更多细节
      • Cookie 实践:记住上次访问时间
      • JSP 入门
      • JSP 的内置对象和案例
      • IDEA 与 JavaWeb 的小技巧
      • Session 笔记
      • 验证码案例
      • JSP 深入学习
      • MVC 开发模式
      • EL 表达式和 JSTL 标签
      • JSTL 标签库
      • 案例:列表的增删改查
      • Filter 学习
      • Filter 案例
        • 过滤器案例 1_登录验证:
        • 过滤器案例 2_敏感词汇过滤
        • 代理的实现
        • 案例 2_敏感词汇过滤实现
        • 总结
      • Listener 学习
      • Java 中的 Ajax
      • Java 中的 JSON
  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaWeb
  • Servlet 入门
2023-04-17
目录

Filter 案例

# 140.Filter 案例

我们做一些小案例,加深对 Filter 的学习

‍

# 过滤器案例 1_登录验证:

# 需求

  1. 访问资源时,要验证其是否登录
  2. 如果登录了,则直接放行。
  3. 如果没有登录,则跳转到登录页面,提示 "您尚未登录,请先登录"。

登录验证是最基础的权限控制,后续我们会学习权限框架。 ‍

# 分析

  1. 我们应该用过滤器,来实现验证登录的功能
  2. 新建一个 LoginFilter 过滤器,首先判断要访问的资源是否要登录后才能访问,如果不是则直接返回,如果是则需要判断是否登录了
  3. 怎么判断是否登录呢?判断 Session 中是否有 User 属性(登录后会将 User 对象放到 Session 中)

注意,有些资源是不需要登录才能访问的,不然就变成套娃了:如果登录页面需要登录后才能访问,那么没有登录的情况下,会自动跳转到登录页面,然后一直跳转,死循环了

示意图:

# 实现

package com.peterjxl.filter;

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

/**
 * 完成登录验证的过滤器
 */
@WebFilter("/*")
public class LoginFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        // 0. 强转为HttpServlet,这样才能获取请求的资源路径
        HttpServletRequest req = (HttpServletRequest) request;
        // 1. 获取请求的资源路径
        String uri = req.getRequestURI();
        if (uri.contains("/login.jsp")
                || uri.contains("/loginServlet")
                || uri.contains("/css/")
                || uri.contains("/js/")
                || uri.contains("/fonts/")
                || uri.contains("/checkCodeServlet/")
        ){
            chain.doFilter(request, response);
        }else {
            // 不包含,需判断是否登录

            // 3. 从Session获取user
            Object user = req.getSession().getAttribute("user");
            if (null == user){
                System.out.println("已登录");
                chain.doFilter(request, response);
            }else {
                // 没有登录
                req.setAttribute("login_msg", "您尚未登录,请登录");
                req.getRequestDispatcher("/login.jsp").forward(request, response);
            }
        }


    }

    public void init(FilterConfig config) throws ServletException {
    }

    public void destroy() {
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

# 过滤器案例 2_敏感词汇过滤

# 需求

  1. 对录入的数据进行敏感词汇过滤
  2. 敏感词汇参考《敏感词汇.txt》
  3. 如果是敏感词汇,替换为 ***

敏感词汇.txt:

笨蛋
坏蛋
1
2

# 分析

  1. 从 request 对象中取出参数,然后过滤掉敏感词汇;但是在 request 对象中,没有重新设置 parameter 的方法,因此我们得考虑,因此我们得对 request 对象做一个“增强”,形成一个新的、过滤好敏感词汇的 request 对象
  2. 放行,传递新的对象给 Servlet。

所以过滤比较简单,麻烦的是如何增强。

什么叫增强对象的功能?其实增强是一种设计模式,就是原始的对象并不能满足我们的需要,我们得给他加上一些功能。可以使用如下设计模式:

  1. 装饰模式,我们在学习 IO 的时候讲过了:Decorator 模式 (opens new window)

  2. 代理模式。我们在讲解 Nginx 的时候,已经说过什么是代理了,而设计模式中的代码模式,就相当于创建一个代理对象,这个代理对象比之前的对象加强了一些功能。这里介绍几个名词: ‍ 代理模式有两种实现模式:

  3. 静态代理:有一个类文件描述代理模式

  4. 动态代理:在内存中形成代理类,用的更多,也是本文要使用的 ‍ 代理模式实现步骤:

  5. 代理对象和真实对象,需要实现相同的接口

  6. 获取代理对象: Proxy.newProxyInstance();,这里需要几个参数,我们后续介绍

  7. 使用代理对象调用方法

  8. 编写代码,增强方法

增强的方式:

  1. 增强参数列表
  2. 增强返回值类型
  3. 增强方法体执行逻辑

# 代理的实现

我们写一些代码来演示代理模式。 ‍ 首先是一个接口:

package com.peterjxl.proxy;

public interface SaleComputer {
    String sale(double money);
    void show();
}

1
2
3
4
5
6
7

‍ 然后是真实对象:(Lenovo 是联想的意思,一个知名的品牌)

package com.peterjxl.proxy;

public class Lenovo implements SaleComputer {
    @Override
    public String sale(double money) {

        System.out.println("花了"+money+"元买了一台联想电脑...");
        return "联想电脑";
    }

    @Override
    public void show() {
        System.out.println("展示电脑....");
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

‍

# Proxy.newProxyInstance()

接下来我们一步步演示创建代理对象,并增强方法。首先在代理模式出现之前,我们想要卖电脑,直接调用 sale 方法即可;

package com.peterjxl.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
    public static void main(String[] args) {
        //1.创建真实对象
        Lenovo lenovo = new Lenovo();


        //2.调用方法
        String computer = lenovo.sale(8000);
        System.out.println(computer);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

‍ 运行结果:

花了8000.0元买了一台联想电脑...
联想电脑
1
2

‍ 假设我们现在是代理商,帮 Lenovo 卖电脑,这样客户不用去美国的 Lenovo 里买了,直接在国内买即可。我们从 Lenovo 里买了电脑并卖出,我们得抽成的,得怎么做?此时我们就可以用到代理对象了,增强 sale 方法 ‍ 我们使用 Proxy.newProxyInstance() 来创建代理对象,该方法需要 3 个参数:

  1. 类加载器:真实对象.getClass().getClassLoader(),固定写法
  2. 接口数组:真实对象.getClass().getInterfaces(),获取真实对象实现的所有接口,也是固定写法,这样能保证代理对象和真实对象实现一样的接口
  3. 处理器:new InvocationHandler(),该 InvocationHandler 接口内部有一个方法,叫做 invoke,我们就是在里面写具体如何增强对象的代码,这也算创建代理对象的重点。

至此,我们可以写出下面的代码,获取代理对象:

Object proxy_lenovo = Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return null;
        }
    });
1
2
3
4
5
6

‍ 由于代理对象和真实对象实现了同样的接口,我们可以强制转换一下:

SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return null;
        }
    });
1
2
3
4
5
6

‍ 将来,我们就可以调用代理对象的 sale 方法了:

String computer = proxy_lenovo.sale(8000);
System.out.println(computer);
1
2

‍

# invoke

那么接下来就是重点了,如何编写增强的代码?这就涉及到 invoke 方法怎么编写了。invoke 方法是什么?简单来说就是代理对象调用的所有方法都会先执行这个方法后,再执行。什么意思呢?我们来实践下,在里面加个输出语句:

package com.peterjxl.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
    public static void main(String[] args) {
        //1.创建真实对象
        Lenovo lenovo = new Lenovo();

        // 2. 动态代理增强 Lenovo对象
        SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("proxy_lenovo对象的invoke方法被执行了.....");
                return null;
            }
        });

        //3.调用方法
        String computer = proxy_lenovo.sale(8000);
        proxy_lenovo.show();
        System.out.println(computer);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

运行结果:

proxy_lenovo对象的invoke方法被执行了.....
proxy_lenovo对象的invoke方法被执行了.....
null
1
2
3

可以看到我们调用了 2 个代理对象的方法,然后输出了 2 次 proxy_lenovo对象的invoke方法被执行了.....,这说明 invoke 方法被执行了 2 次。

接下来我们讲讲 invoke 方法的 3 个参数:

public Object invoke(Object proxy, Method method, Object[] args)
1

每个参数的含义:

  1. proxy:代理对象,就是指本次创建的代理对象,一般不会用到这个参数
  2. method:代理对象调用的方法,被封装为的对象。例如上例中 method 分别是 sale 和 show 方法
  3. args:代理对象调用的方法时,传递的实际参数,例如 sale 传了参数 8000.

我们可以打印下这几个参数:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.print("proxy_lenovo对象的invoke方法被执行了..... ");
    System.out.print("method名字: " + method.getName());
    System.out.println("  method参数: " + Arrays.toString(args));
    return null;
}
1
2
3
4
5
6

运行结果:

proxy_lenovo对象的invoke方法被执行了..... method名字: sale  method参数: [8000.0]
proxy_lenovo对象的invoke方法被执行了..... method名字: show  method参数: null
null
1
2
3

‍ 需要注意的是,虽然传递了 Method 对象,但是具体的方法是没有被调用的!我们真实对象 Lenovo 里,sale 方法调用的时候会输出 System.out.println("花了"+money+"元买了一台联想电脑...");,但我们之前测试代理对象的时候,这句输出语句一直没有被执行。

如果想要调用真实对象的方法,还得这样做:

metnod.invoke(lenovo, args);
1

‍ 并且,invoke 方法的返回值就是调用真实对象方法的返回值,所以我们可以返回该结果,这样调用代理对象的方法就能有返回值了:

Object result = method.invoke(lenovo, args);
return result;
1
2

# 增强方法

接下来我们就可以增强方法了,有如下增强的方式:

  1. 增强参数列表
  2. 增强返回值类型
  3. 增强方法体执行逻辑 ‍

# 增强参数列表

我们之前是花了 8000 从联想买了一台电脑,但我们现在是从代理商买的,代理商得涨价,所以得对参数做调整,例如涨价 10%:

if(method.getName().equals("sale")){
    double money = (double) args[0];
    money *= 1.1;
    Object result = method.invoke(lenovo, money);
    return result;
}else {
    Object result = method.invoke(lenovo, args);
    return result;
}
1
2
3
4
5
6
7
8
9

此时我们调用代理对象的话,就得话更多的钱买:

proxy_lenovo.sale(8000);
1

‍ 运行结果:

花了8800.0元买了一台联想电脑...
1

# 增强返回值

我们刚刚花了 8800 才买了一台电脑,代理商为了平衡我们的心情,想多送键盘和鼠标给我们,可以怎么做呢?修改返回值:

 if(method.getName().equals("sale")){
    double money = (double) args[0];
    money *= 1.1;
    Object result = method.invoke(lenovo, money);
    return result + "键盘和鼠标";
}else {
    Object result = method.invoke(lenovo, args);
    return result;
}
1
2
3
4
5
6
7
8
9

‍ 此时返回值就是 联想电脑键盘和鼠标

# 方法体增强

比如我们想要在执行真实对象的方法前,先执行一些输出语句(或者记录一些日志),可以在调用方法前写代码:

if(method.getName().equals("sale")){
    System.out.println("专车接送买电脑.....");
    double money = (double) args[0];
    money *= 1.1;
    Object result = method.invoke(lenovo, money);
    System.out.println("免费送货.....");
    return result + "键盘和鼠标";
}
1
2
3
4
5
6
7
8

# 完整代码

package com.peterjxl.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
    public static void main(String[] args) {
        //1.创建真实对象
        Lenovo lenovo = new Lenovo();
        //2.动态代理增强lenovo对象
        SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //判断是否是sale方法
                if(method.getName().equals("sale")){
                    //1.增强参数
                    double money = (double) args[0];
                    money = money * 0.85;
                    System.out.println("专车接你....");
                    //使用真实对象调用该方法
                    String obj = (String) method.invoke(lenovo, money);
                    System.out.println("免费送货...");
                    //2.增强返回值
                    return obj+"_鼠标垫";
                }else{
                    Object obj = method.invoke(lenovo, args);
                    return obj;
                }
            }
        });
        //3.调用方法
        proxy_lenovo.show();
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

‍

# 案例 2_敏感词汇过滤实现

至此,我们就可以增强 request 方法了

  1. 在 init 方法里加载敏感词汇
  2. 创建一个代理对象,从 request 对象中取出参数,然后过滤掉敏感词汇;
  3. 放行,传递新的对象给 Servlet。 ‍

# 在 init 方法里加载敏感词汇

在 src 目录下新建一个《敏感词汇.txt》,注意修改文件编码格式为 GBK(因为 Windows 下默认是这个)

然后在 Filter 的 init 方法里加载敏感词汇,并放到一个 List 数组里:

 @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        try {
            // 1. 加载文件
            ServletContext servletContext = filterConfig.getServletContext();
            String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");
            BufferedReader bufferedReader = null;

            // 2. 读取文件
            bufferedReader = new BufferedReader(new FileReader(realPath));

            // 3. 将文件的每一行放到list
            String line = null;
            while( (line = bufferedReader.readLine()) != null) {
                list.add(line);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 增强 getParameter 方法

我们增强 getParameter 方法:

  1. 创建代理对象
  2. 判断方法名是不是 getParameter,如果不是则执行方法并返回 return method.invoke(servletRequest, args);
  3. 如果是,则获取该值,并做过滤处理,将过滤后的值返回 ‍ 代码:
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(servletRequest.getClass().getClassLoader(), servletRequest.getClass().getInterfaces(), new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 增强getParameter方法
            if (method.getName().equals("getParameter")){
                String value = (String) method.invoke(servletRequest, args);
                if( null != value){
                    for(String str : list){
                        if(value.contains(str)){
                            value = value.replaceAll(str, "***");
                        }
                    }
                }

                return value;   //返回过滤后的字符
            }
            return method.invoke(servletRequest, args);
        }
    });
    filterChain.doFilter(proxy_req, servletResponse);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 完整代码

package com.peterjxl.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * 敏感词汇过滤器
 */

@WebFilter("/*")
public class SensitiveWordsFilter implements Filter {
private List<String> list = new ArrayList<>(); //敏感词汇集合
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(servletRequest.getClass().getClassLoader(), servletRequest.getClass().getInterfaces(), new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 增强getParameter方法
            if (method.getName().equals("getParameter")){
                String value = (String) method.invoke(servletRequest, args);
                if( null != value){
                    for(String str : list){
                        if(value.contains(str)){
                            value = value.replaceAll(str, "***");
                        }
                    }
                }

                return value;   //返回过滤后的字符
            }
            return method.invoke(servletRequest, args);
        }
    });
    filterChain.doFilter(proxy_req, servletResponse);
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {
    try {
        // 1. 加载文件
        ServletContext servletContext = filterConfig.getServletContext();
        String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");
        BufferedReader bufferedReader = null;

        // 2. 读取文件
        bufferedReader = new BufferedReader(new FileReader(realPath));

        // 3. 将文件的每一行放到list
        String line = null;
        while( (line = bufferedReader.readLine()) != null) {
            list.add(line);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

# 测试

我们新建一个 SensitiveWordsFilterTest 类,用来测试 getParameter 方法

package com.peterjxl.filter;

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

@WebServlet("/sensitiveWordsFilterTest")
public class SensitiveWordsFilterTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        System.out.println("name = " + name);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

‍ 重启 Tomcat,访问

http://localhost:8080/hello/sensitiveWordsFilterTest?name=张三大坏蛋
1

‍ 可以看到控制台输出了

name = 张三大***
1

‍ 这里只增强了 getParameter 方法,其实还有一些获取参数的方法要增强,就不一一实现了:

req.getParameterMap();
req.getParameterValues()
1
2

‍

# 总结

代理是一个非常重要的概念,后续我们学习很多框架,其底层都是用了代理的方式。

上次更新: 2025/6/3 09:31:54
Filter 学习
Listener 学习

← Filter 学习 Listener 学习→

最近更新
01
学点统计学:轻松识破一本正经的胡说八道
06-05
02
2025 年 5 月记
05-31
03
《贫穷的本质》很棒,但可能不适合你
05-27
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式