Filter && Listener

课程笔记Day42

  • 过滤器 Filter
  • 监听器 Listener

第一章 过滤器Filter

第01节 基础理论
1、概念说明
1. 什么是过滤器?
	过滤器就是 Filter 他是JavaWeb的三大组件之一。
	三大组件:  Servlet、Filter、Listener

2. 过滤器有什么作用呢?
	可以去拦截或者增强, 请求(request)和响应(response)

3. 应用场景有哪些呢?
	自动登录
	统一的编码设置
	访问权限控制
	敏感词过滤

生活实例
在这里插入图片描述

2、操作步骤
1. 如果是 XML 版本:
	A. 写一个类去实现 Filter 接口 
	B. 重写方法 init()、doFilter()、destroy()
	C. 在 web/WEB-INF/web.xml 当中配置过滤器

2. 如果是 注解 版本:
	A. 写一个类去实现 Filter 接口
	B. 重写方法 init()、doFilter()、destroy()
	C. 在 类的上面添加注解 @WebFilter("过滤的规则等")
第02节 快速入门
1、filer过滤器实现类

位置 src/com.chc01.DoorFilter

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

public class DoorFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("DoorFilter.init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("DoorFilter.doFilter ... 放行前");
        //放行,才能往下执行。
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("DoorFilter.doFilter ... 放行后");
    }

    @Override
    public void destroy() {
        System.out.println("DoorFilter.destroy");
    }
}
2、web.xml的配置

位置 web/WEB-INF/web.xml

<filter-mapping>
    <filter-name>DoorFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>DoorFilter</filter-name>
    <filter-class>blb.chc02.DoorFilter</filter-class>
</filter>
3、Servlet的代码实现

位置 src/blb.chc02.DoorServlet

/***
 * 访问地址: http://localhost:8080/JavaWebDay20/DoorServlet
 */

@WebServlet("/DoorServlet")
public class DoorServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("DoorServlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("DoorServlet.doPost");
    }
}
第03节 统一编码
1、CodeFilter

位置 src/blb.chc03.CodeFilter

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

//写一个类 去实现过滤器的接口 Filter
@WebFilter("/*")
public class CodeFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CodeFilter.init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("CodeFilter.doFilter...执行前...");
        //----------------
        //可以给请求进行增强,设置统一的编码方式
        servletRequest.setCharacterEncoding("UTF-8");
        //可以给响应进行增强,设置响应文本信息
        servletResponse.setContentType("text/html;charset=UTF-8");
        //----------------
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("CodeFilter.doFilter...执行后...");
    }

    @Override
    public void destroy() {
        System.out.println("CodeFilter.destroy");
    }
}
2、CodeServlet

位置 src/blb.chc03.CodeServlet

/*** 
 * 访问地址: http://localhost:8080/JavaWebDay20/CodeServlet?username=张三&password=1234
 */
@WebServlet("/CodeServlet")
public class CodeServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("CodeServlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("CodeServlet.doPost");
        //获取到请求的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //展示结果
        if (username!=null && password!=null){
            System.out.println("username = " + username);
            System.out.println("password = " + password);
            //回复数据
            resp.getWriter().println(username+","+password);
        }
    }
}
第04节 三个细节
1、urlpatten 的写法

过滤参数的四种写法

编号代码说明
1/*拦截所有的URL信息
2/dir/*拦截URL信息,在dir下面的会被拦截到
3*.jsp拦截URL信息,jsp 文件会被拦截到

案例代码

位置: blb.chc04.DemoUrl01Filter

//拦截war包下面,dir文件夹下面的所有信息
@WebFilter("/dir/*")
public class DemoUrl01Filter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("DemoUrl01Filter.init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("DemoUrl01Filter.doFilter");
        System.out.println("拦截war包下面,dir文件夹下面的所有信息");
        //...
    }

    @Override
    public void destroy() {
        System.out.println("DemoUrl01Filter.destroy");
    }
}

位置: blb.chc04.DemoUrl02Filter

//拦截war包下面所有的 jsp文件
@WebFilter(urlPatterns={"*.jsp"})
public class DemoUrl02Filter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("DemoUrl02Filter.init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("DemoUrl02Filter.doFilter");
        System.out.println("拦截war包下面所有的 jsp文件");
        //...
    }

    @Override
    public void destroy() {
        System.out.println("DemoUrl02Filter.destroy");
    }
}
2、过滤器参数配置

过滤参数的五种写法 dispatcherTypes

编号枚举类型说明
1FORWARD转发,当出现请求转发的时候,触发过滤器
2INCLUDE包含,当出现请求包含的时候,触发过滤器
3REQUEST请求,当发起请求的时候,触发过滤器
4ASYNC异步,当出现异步请求的时候,会触发过滤器
5ERROR出错,当出现错误信息的时候,触发过滤器

案例代码

代码位置 src/blb.chc05.ForwardFilter

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

/***
 * 用于请求转发的过滤器
 * urlPatterns = "/*"  表示拦截所有的
 * dispatcherTypes = DispatcherType.FORWARD  拦截请求转发的
 */
@WebFilter(urlPatterns = "/*",dispatcherTypes = DispatcherType.FORWARD)
public class ForwardFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("ForwardFilter.init");
    }


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("ForwardFilter.doFilter....前");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("ForwardFilter.doFilter....后");
    }

    @Override
    public void destroy() {
        System.out.println("ForwardFilter.destroy");
    }
}

代码位置 src/blb.chc05.Forward01Servlet

@WebServlet("/Forward01Servlet")
public class Forward01Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Forward01Servlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Forward01Servlet.doPost");
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().println("Forward01Servlet....");
        //定义请求转发的代码
        req.getRequestDispatcher("/Forward02Servlet").forward(req,resp);
    }
}

代码位置 src/blb.chc05.Forward02Servlet

@WebServlet("/Forward02Servlet")
public class Forward02Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Forward02Servlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Forward02Servlet.doPost");
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().println("Forward02Servlet....");
    }
}
3、过滤器先后顺序问题

说明

1. 在我们的 web.xml 当中,如果采用的是 XML形式配置的过滤器。 谁写在上面,谁的优先级越高。
2. 如果我们采用的是注解的方式进行的配置,则会出现 过滤器类名称的顺序,字符串字典顺序,小的在前,大的在后。

案例

<filter-mapping>
    <filter-name>Order01Filer</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>Order01Filer</filter-name>
    <filter-class>blb.chc06.Order01Filer</filter-class>
</filter>


<filter-mapping>
    <filter-name>Order02Filer</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>Order02Filer</filter-name>
    <filter-class>blb.chc06.Order02Filer</filter-class>
</filter>


<filter-mapping>
    <filter-name>Order03Filer</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>Order03Filer</filter-name>
    <filter-class>blb.chc06.Order03Filer</filter-class>
</filter>

说明:

配置的方式是 从上往下分别是 01-02-03

请求开启的顺序是 01->02->03

响应开启的顺序是 03->02->01


采用注解的方式配置过滤器

过滤器 Order01Filer

@WebFilter("/*")
public class Order01Filer implements Filter {
	.....
}

过滤器 Order02Filer

@WebFilter("/*")
public class Order02Filer implements Filter {
	.....
}

过滤器 Order03Filer

@WebFilter("/*")
public class Order03Filer implements Filter {
	.....
}

说明:

配置的方式是 从上往下分别是 Order01Filer-Order02Filer-Order03Filer

请求开启的顺序是 01->02->03

响应开启的顺序是 03->02->01

第二章 监听器 Listener

第01节 基础理论
1、概念说明
1. 什么是监听器?
	过滤器就是 Listener 他是JavaWeb的三大组件之一。
	三大组件:  Servlet、Filter、Listener

2. 监听器有什么作用呢?
	目前来说,作为一个简单的了解就行了,因为后期框架当中会对监听器进行包装。
	我们可以采用监听器,去实时监听变化的数据。
	例如: 在线直播的人数,实时变化。
2、操作步骤
1. 写一个类去实现接口
2. 重写方法,创建的方法和销毁的方法
3. 配置,可以采用 xml 配置,也可以采用 注解配置
3、八个常用接口

监听四大域对象的接口,只有三个。其中页面域不在范围内。

ServletContextListener
HttpSessionListener
ServletRequestListener

监听四大域对象属性的接口。只有三个。其中页面域不在范围内。

ServletContextAttributeListener
HttpSessionAttributeListener
ServletRequestAttributeListener

监听会话感知型的接口。会话域,可以进行永久性保存。钝化和活化

HttpSessionBindingListener
HttpSessionActivationListener
第02节 快速入门
1、DoorListener

位置 src/blb.chc07.DoorListener

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class DoorListener implements ServletRequestListener {

    //请求销毁的时候,调用此方法
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("DoorListener.requestDestroyed...销毁");
    }

    //请求初始化的时候,调用此方法
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("DoorListener.requestInitialized...初始化");
    }
}
2、DoorServlet

位置 src/blb.chc07.DoorServlet

/***
 * 访问地址: http://localhost:8080/JavaWebDay20/DoorServlet
 */

@WebServlet("/DoorServlet")
public class DoorServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("DoorServlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("DoorServlet.doPost");
    }
}
第03节 记录用户流量
1、需求说明
俊杰在抖音开直播,晒豪车,保时捷 Panamera
现在吸引了很多忠实的小粉丝过来观看。
最后在结束直播之后,需要去查看流量。
有多少人观看了直播。

说明: 只要开启了直播界面,我们就要计数。开启计数器,不断的增加。
2、案例代码

位置 src/blb.chc08.LiveListener

import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;

/***
 * 写一个类,实现接口 ServletRequestListener
 */
@WebListener
public class LiveListener implements ServletRequestListener {

    //定义计数器, 准备用于记录观看直播的人数。
    private int count = 0;

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        //强制类型转换,成为http请求
        HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
        String uri = request.getRequestURI();
        //含义是:只有在直播的 Servlet 当中才去做记录,否则不去记录
        if (uri.contains("/LiveServlet")) {
            System.out.println("LiveListener.requestInitialized....嘻嘻,小伙,又来看我啦...");
            //只要有人来观看直播,计数器就要增加
            count++;
            //还需要把数据保存起来,可以采用会话对象保存
            request.getSession().setAttribute("count", count);
        }
    }
}

位置 src/blb.chc08.LiveServlet

/**
 * 直播的 Servlet
 * 访问地址:  http://localhost:8080/JavaWebDay20/LiveServlet
 */
@WebServlet("/LiveServlet")
public class LiveServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("LiveServlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("LiveServlet.doPost");
        //直接获取到会话域的数据
        Object count = req.getSession().getAttribute("count");
        //展示结果到浏览器当中
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().println("当前浏览量:"+count);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值