Filter&Listener

1.Web三大件

Servlet,Filter,Listener

2.Filter过滤器

2.1概念

Filter 过滤器它是 JavaEE 的规范。也就是接口
Filter 过滤器它的作用是:拦截请求,过滤响应

2.2案例

服务器中的资源--》 图片,css,js,音频视频,html,jsp 等都是资源

2.2.1第一步:编写一个Filter 通过实现Filter接口

package com.qfedu.filter;

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

public class Demo01Filter implements Filter {

    // init 方法   ==-》 Filter创建的时候调用
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        System.out.println("我被创建了....");
    }

    // 当程序被拦截器拦截之后,会执行doFilter里面的代码
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("这是我的第一个过滤器");
        // 获取到资源之后,根据条件选择是否放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    // filter即将回收的时候调用
    @Override
    public void destroy() {

        System.out.println("我即将被回收");
    }
}

这个里面有三个方法:
init --> 该Filter被创建的时候调用,只调用一次
destory--> 该Filter对象被销毁的时候调用,也只调用一次
doFilter --> 核心方法,过滤器没拦截一次请求,就执行一次方法。
不管是做什么操作,记得放行:
filterChain.doFilter(servletRequest,servletResponse);

2.2.2第二步: 配置Filter

  1. 在web.xml中编写xml
<filter>
        <filter-name>filter01</filter-name>
        <filter-class>com.qfedu.filter.Demo01Filter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter01</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2)注解的方案: @WebFilter("/*")

2.2.3过滤器拦截规则和执行顺序

执行顺序:
浏览器 --> 过滤器去拦截 --> 获取资源 --> 又到 过滤器这里--> 过滤器放行-->浏览器展示资源

问题:如果有两个 过滤器,都满足拦截条件,先执行哪个,后执行哪个?
1、如果你是注解配置的方式编写的过滤器:执行顺序按照类名进行比较
AFilter BFilter A先执行,B后执行
A10Filter A2Filter 先执行A10Filter ,后执行A2Filter.
2、web.xml方式编写的配置
定义在最前面的,先执行,定义在后面的后执行
一个项目中,要么都使用xml,要么都使用注解,所以注解和xml混着写的方式一般不存在。

拦截的规则有如下几种写法:
1、拦截具体的路径 /index.jsp 只拦截index.jsp
2、拦截目录: /customer/* 只拦截以customer开头的二级访问路径
3、拦截以某种后缀名结尾的请求 *.do *.action .jsp
4、拦截所有请求 /

在过滤器中,还可以设置拦截被访问的方式 DispatcherType 【了解】
DispatcherType

  • REQUEST: 默认值,拦截浏览器直接请求的资源,类似于重定向
  • FORWARD: 内部转发 只拦截内部转发的资源
  • INCLUDE: 一个资源被包含在另一个资源中,发出的请求
  • ERROR: 错误跳转的资源
    
  • ASYNC: 异步访问的资源
    

2.3实战

通过过滤器实现,只有登录后才能访问操作系统中的资源

package com.qfedu.filter;

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

@WebFilter({"/customer/*"})
public class LoginFilter implements Filter {


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    // ServletRequest   是  HttpServletRequest的父类
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("进入到登录过滤器");
        HttpServletRequest req = ((HttpServletRequest) servletRequest);
        // 先判断该用户有没有登录,如果没有登录,直接跳转到登录页面
        HttpSession session =req.getSession();
        Object obj = session.getAttribute("USERNAME");
        if(obj!=null){
            // 如果判断登录过了,直接放行
            filterChain.doFilter(servletRequest,servletResponse);
        }else{
            // 没有登录过,跳转到登录页面
            ((HttpServletResponse)servletResponse).sendRedirect(req.getContextPath()+"/login.jsp");
        }



    }

    @Override
    public void destroy() {

    }
}

字符集的一个设置:
我们有很多页面,都需要设定字符集,防止中文乱码 编写一个字符集过滤器,为指定的servlet设置字符集,以后就不用我们设置了。

3.Listener--> 监听器

Java Web监听器很多中,最常用的,以后能用的上的,就这一种:ServletContextListener
监听ServetContext的诞生的。
如果ServletContext对象被创建了,就会触发ServletContextListener中的代码。
ServletContext对象有什么用,它创建不创建跟我的代码有什么关系?
ServletContext对象是在tomcat已启动就被创建的,被tomcat所创建。
换句话说:当一个项目已启动就会触发ServletContextListerner.
我们可以将项目启动时需要加载的数据或者资源放入到该ServletContextListener中。

项目中的真实案例:
群发短信功能---> 每一个手机号码都需要进行一个红名单的校验
红名单:此类手机号码千万不要给它发垃圾短信。
红名单的数据在你们公司的数据库中,大约有100多万条。
发短信要校验红名单。
项目一启动,就开始查询红名单数据,将数据存放在内存中,将来拿到一个手机号去校验是否是红名单数据就非常快。

代码演示

package com.qfedu.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class ContextLoaderListener implements ServletContextListener {

    //监听ServletContext被创建就执行如下代码
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {

        System.out.println("servletContext被创建了");
    }

    //监听ServletContext被销毁,触发如下代码
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("servletContext被销毁了");
    }
}

Listener编写完之后也有两种配置方案
xml

    <listener>
        <listener-class>com.qfedu.listener.ContextLoaderListener</listener-class>
    </listener>

注解方案: @WebListener

监听器什么时候执行,不是由我们决定的,而是监听器本身监听的对象决定,监听器监听的对象发生改变了,监听器中的代码就自动执行了。一个对象,同一个动作一般只有一个监听器。我们学习的是ServletContextListener!

4.总结三大组件

1、web.xml中都可以写什么内容?
项目中的web.xml其实是tomcat服务器中web.xml的子集。它可以配置servlet,Filter,Listener
welcome-file-list 设置欢迎页,还可以设置一些参数 context_param。

2、各个组件之间的执行顺序说一下?
web.xml中加载顺序: --> listener --> filter --> servlet
filter如果是多个,加载顺序怎样。
servlet很多,加载顺序如何?load-on-startup 有关系。

3、三大组件共同的特点
编写完代码之后,必须进行配置,配置都分为两种 xml 和 注解

posted @ 2021-09-20 10:25  码丁XIA  阅读(42)  评论(0)    收藏  举报