过滤器和监听器-java学习记录

过滤器:

过滤器运行在客户端与web资源之间的,用户请求到达web资源之前,先会执行过滤器。
web资源:放在服务器上各种资源,如:JSP,Servlet,HTML,图片,CSS

  1. 请求进行修改

  2. 对请求进行拦截

过滤器的使用场景:

  1. 全局乱码问题解决。以前POST方法提交给Servlet时候,汉字有乱码问题。(没有请求体,只在地址栏显示)现在可以通过过滤器来集合解决。

  2. 用户权限验证,对没有登录的用户进行判断。

  3. 对请求的内容进行过滤,过滤掉一些广告,不健康的信息。(作业)

开发过滤器的步骤

  1. 创建一个类实现javax.servlet.Filter接口
  2. 重写接口中所有的方法,其中doFilter() 用来执行过滤任务的
  3. 需要配置web.xml或使用注解@WebFilter来配置过滤器
    开发一个过滤器
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "Demo1HelloServlet", urlPatterns = "/Demo1Hello")
public class Demo1HelloServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Web资源:Servlet执行");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

使用注解的方式

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

/*
1. 创建一个类实现javax.servlet.Filter接口
2. 重写接口中所有的方法,其中doFilter() 用来执行过滤任务的
3. 需要配置web.xml或使用注解@WebFilter来配置过滤器
 */
//@WebFilter("/Demo1Hello")  //要过滤的地址
@WebFilter(filterName = "demo1", urlPatterns = "/Demo1Hello")
public class Demo1HelloFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器:请求的时候执行");
        //调用这个方法放行,如果没有调用这个方法,请求会被拦截
        filterChain.doFilter(request, response);
        System.out.println("过滤器:响应的时候执行");
    }

    @Override
    public void destroy() {

    }
}

使用配置文件的方式

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 配置过滤器-->
    <filter>
        <!-- 过滤器的名字-->
        <filter-name>demo1</filter-name>
        <!-- 过滤器的类全名-->
        <filter-class>com.itheima.filter.Demo1HelloFilter</filter-class>
    </filter>
    <!--配置过滤的地址-->
    <filter-mapping>
        <!-- 过滤器的名字和上面的名字一样-->
        <filter-name>demo1</filter-name>
        <!-- 这是过滤的地址,是web资源的地址-->
        <url-pattern>/Demo1Hello</url-pattern>
    </filter-mapping>
</web-app>

过滤器的执行特点

并没有主动去调用过滤器,如果我们访问的web资源匹配过滤器的过滤地址,则过滤器会自动执行。

过滤器的执行流程

  1. 用户发送请求,请求的是web资源地址。
  2. 如果过滤器匹配这个资源的地址,就会先执行过滤器
  3. 执行过滤器中doFilter()过滤方法,如果要将请求放行,调用chain.doFilter(request, response)方法。将请求和响应对象放行。
  4. 到达web资源,web资源访问完成以后,响应回来,还会再次经过过滤器。
  5. 返回到浏览器端
    image.png

1.服务器启动,加载项目就初始化。
2. 过滤的方法每次请求都执行
3. 过滤器服务器关闭销毁
image.png
过滤器匹配多个地址

@WebFilter({"/demo1", "/demo2"})同时过滤demo1和demo2
@WebFilter({"/admin/*", "*.jsp"})过滤admin目录下所有的资源和所有的JSP页面,过滤的地址是所有过滤地址的并集,不是交集

在Servlet3.0中一共有5种拦截方式,常用的有2种。

  1. FORWARD 转发
  2. REQUEST 请求
    如果没有指定拦截方式,默认是REQUEST。只对直接从浏览器访问的请求起作用。
    注解的方式拦截:
    dispatcherTypes 指定拦截方式
    DispatcherType.FORWARD 转发的时候拦截
    DispatcherType.REQUEST 请求的拦截
    ###过滤器链
    在一个项目可以同时存在多个过滤器,每个过滤器实现一个不同的功能,有利于模块化的设计。
    多个过滤器过滤同一个地址,多个过滤器就形成了一个过滤器链,如果下一个是过滤器则将请求和响应传递给下一个过滤器,如果下一个不是过滤器,就将请求和响应传递给web资源。而响应回来的时候,会再次经过所有的过滤器。

FilerChain接口就表示过滤器链

image.png

监听器

  1. 作用:用来监听上下文域的创建和销毁, 监听作用域中键和值的改变
  2. 创建时机:服务器启动,并且加载当前项目的时候
  3. 销毁时机:服务器关闭的时候

image.png

package com.itheima.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.sql.Timestamp;

/*
1. 编写1个类实现ServletContextListener接口
2. 重写接口中所有的方法
3. 使用配置<listener>或使用注解@WebListener
 */
@WebListener
public class MyContextListener implements ServletContextListener {
    //监听上下文对象创建的事件
    @Override
    public void contextInitialized(ServletContextEvent se) {
        System.out.println(new Timestamp(System.currentTimeMillis()) + ",创建了上下文对象:" + se.getServletContext());
    }

    //监听上下文对象销毁的事件
    @Override
    public void contextDestroyed(ServletContextEvent se) {
        System.out.println(new Timestamp(System.currentTimeMillis()) + ", 销毁上下文对象");
    }
}

大神写的监听器入门:
https://juejin.im/post/5a7d63355188257a7349bbb0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值