JavaWeb基础 - Filter&Listener(跟着做,你怎会不会?)

大家好,我是一只学弱狗,记录学习的点点滴滴!

优质文章

优质专栏


从没有白费的努力,也没有碰巧的成功。只要认真对待生活,终有一天,你的每一份努力,都将绚烂成花。

通过本文,你可以学到

  • 什么是Filter?有什么作用?如何使用?
  • 什么是代理模式?其作用是什么?
  • 案例演示:登陆验证功能实现
  • 案例演示:敏感词汇过滤
  • 什么是Listener及其如何使用?

Filter

概念

Filter,即过滤器,其功能是当客户端浏览器向服务器发送资源请求时,过滤器可以将请求拦截下来,完成一些特殊的功能,我们来看下百度百科上面的介绍:Filter可以使用户改变一个request和修改一个response,它不是一个Servlet,不能产生一个response,它能够在一个request到达Servlet之前预处理request,也可以在response离开Servlet后处理response

使用方法

Servlet、Filter和Listener是Java Web的三大组件,它们在使用方面及其相似,小伙伴们可以先回顾一下Servlet的使用,也要两种方式,其一:配置web.xml文件,其二:使用注解。

配置文件

首先,我们需要在声明一个类,使得这个类呢实现Filter接口,实现其方法。
在这里插入图片描述还没完,我们需要在web.xml文件中配置一下
在这里插入图片描述
记住:Filter中的url-pattern需要配置的是拦截路径,而Servlet中的yrl-pattern配置的是访问资源路径
在这里插入图片描述注意代码执行的顺序,下面我们将具体的阐述

注解

在这里插入图片描述

执行流程

通过上面的代码演示,不难发现,过滤器的执行顺序是这样的

  1. 执行过滤器中放行代码之前的代码
  2. 执行需要访问的资源
  3. 回来继续执行放行代码下边的代码
深度剖析
生命周期方法

和Servlet一样,Filter的init方法是在服务器启动后,会创建Filter对象,然后调用其init方法,只执行一次,一般用于加载资源;destroy是在服务器正常关闭后,会调用destroy方法,只执行一次,用于释放资源;而doFilter方法,在每一次请求被拦截时,会执行,故会执行多次。

拦截路径配置
  1. 具体资源路径
    在这里插入图片描述在这里插入图片描述

  2. 拦截目录
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

  3. 后缀名拦截
    在这里插入图片描述
    在这里插入图片描述

  4. 拦截所有资源
    在拦截路径中填写“/*”即可。

拦截方式配置

拦截方式:指资源被访问的方式。什么意思呢?举个例子,一个资源,我们可以使用URL路径直接访问,也可以通过请求转发去访问,同样都可以访问到这个资源,但是其方式是不一样的,明白了这一点,我们就可以继续往下聊了。
首先拦截方式有以下几个取值:

拦截方式描述
REQUEST默认值,浏览器直接请求资源
FORWARD转发访问资源
INCLUDE包含访问资源
ERROR错误跳转资源
ASYNC异步访问资源

下面,我们先来演示下最基本的REQUEST拦截方式。
直接访问ServletDemo3,会触发拦截
在这里插入图片描述下同通过转发来访问ServetDemo3,并没有触发过滤器

在这里插入图片描述那我们该如何去设置拦截方式呢?同样的,通过注解,获取配置文件
先说注解配置
在这里插入图片描述我们再通过转发的方式访问ServletDemo3的资源时,也可以触发过滤器了
在这里插入图片描述
再着,就是通过配置文件,在< filter-mapper >标签下设置< dispatcher >标签即可。
在这里插入图片描述

过滤器链

大家有没有考虑过这么一种情况,当访问某个资源时,我们有时候需要多个过滤器,那么这样的话就又会产生两个问题,第一个:假设现在有两个过滤器,那么他们谁先执行?谁后执行呢?第二个,如果我们规定了他们的顺序,那么他们的执行顺序又是怎样的呢?就上面两个问题,我们展开如下的探讨。

过滤器先后顺序问题
  • 注解配置:按照类名的字符串比较规则,值小的先执行

在这里插入图片描述

  • web.xml配置:< filter-mapping >谁定义在上边,谁先执行

在这里插入图片描述

执行顺序

从上面也可以看到,两个过滤器的执行顺序向一个栈,即

  1. 过滤器1
  2. 过滤器2
  3. 资源
  4. 过滤器2
  5. 过滤器1

代理模式

这里我就不做多余的解释了,给你个糖果

验证验证功能

敏感词汇过滤


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

@WebFilter("/servletDemo")
public class FilterDemo implements Filter {
    private List<String> list = new ArrayList<>();

    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //解决中文乱码问题
        req.setCharacterEncoding("utf-8");
        ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if ("getParameter".equals(method.getName())) {
                    String value = (String) method.invoke(req, args);
                    if (null != value) {
                        for (String str : list) {
                            if(value.contains(str)){
                                value = value.replaceAll(str,"***");
                            }
                        }
                    }
                    return value;
                }
                return method.invoke(req, args);
            }
        });
        chain.doFilter(proxy_req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
/*        String path = FilterDemo.class.getClassLoader().getResource("敏感词汇.txt").getPath();
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(path));
            String str = null;
            while ((str = br.readLine()) != null) {
                list.add(str);
            }
            System.out.println(list);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }*/

        ServletContext servletContext = config.getServletContext();
        String path = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(path));
            String str = null;
            while ((str = br.readLine()) != null) {
                list.add(str);
            }
            System.out.println(list);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

Listener

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只学弱狗!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值