过滤器Filter和监听器Listener

1、过滤器Filter

1.1、Filter概念

过滤器: 过筛子,符合条件的过去,不符合条件不能过去.

生活比喻: 安检,检查安全的人与物才可以通过放行

程序: 客户端需要访问服务器的目标资源,在客户端和服务器资源之间设置过滤器, 符合要求放行

1.2、Filter的入门程序

需求:

   ●浏览器要访问Servlet

   ●途径过滤期Filter, 若Filter放行,可执行访问到Servlet; 若不放行,无法访问Servlet

执行图解:
在这里插入图片描述
实现步骤

  1. 编写Servlet, 在web.xml配置Servlet访问路径
  2. 编写Filter,定义类, 实现接口Filter, 实现接口中抽象方法, 在web.xml配置Filter的访问过滤路径

代码:Servlet

package com.bdit;

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;
import java.io.PrintWriter;

@WebServlet(urlPatterns = {"/hello2"})
public class HelloServlet 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 {
        System.out.println("====================HelloServlet===============");
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().print("<p>经过过滤器到达类HelloServlet</p>");
    }
}

代码:Filter

package com.bdit;

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


public class HelloFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("=========请求到达过滤器=======");

        filterChain.doFilter(servletRequest,servletResponse);

        System.out.println("============响应到达过滤器===========");
    }
}

代码:web.xml

<?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">


    <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.bdit.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>


    <!--配置过滤器-->
    <filter>
        <filter-name>helloFilter</filter-name>
        <filter-class>com.bdit.HelloFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>helloFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

<!--如果有两个过滤器按照配置顺序执行-->
    <filter>
        <filter-name>helloFilter2</filter-name>
        <filter-class>com.bdit.HelloFilter2</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>helloFilter2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

1.3、Filter的生命周期

●过滤器对象的创建,是Tomcat服务器启动(而Servlet默认是第一个请求到达时)
   ○init(FilterConfig config)过滤器对象被创建的时候调用,FilterConfig 对象tomcat引擎创建

●过滤器执行过滤的方法,过滤被访问资源的时候,必须是被过滤器过滤器的资源
   ○doFilter(request,response)

●过滤器对象销毁的方法,销毁之前调用,服务器关闭
   ○destroy()

1.4、Filter的url-pattern配置

完全匹配:

<!--
	过滤资源,只有hello
	绝对匹配<url-pattern>/hello</url-pattern>
	只能过滤指定的资源
-->
<url-pattern>/hello</url-pattern>

目录匹配:

<!--
	目录匹配,过滤器中最常见
	/abc/* 过滤abc目录下的所有资源
	一次过滤一片资源
	过滤后台资源/admin/*
-->
<url-pattern>/admin/*</url-pattern>

后缀名匹配:

<!--
	后缀名匹配,一般不使用
	*.jsp 访问所有jsp文件
-->
<url-pattern>*.jsp</url-pattern>

1.5、注解配置Filter

@WebFilter(urlPatterns="/过滤资源")

@WebFilter("/*")
public class ChinaFilter implements Filter{
//代码省略...
}

1.6、Filter处理中文乱码

需求:使用过滤器Filter, 处理所有请求的中文乱码

代码:Filter

package com.bdit.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(urlPatterns = {"/safe/*"})
public class TreeFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("test/html;charset=UTF-8");
     
		filterChain.doFilter(request,response);
    }
}

1.7、过滤器链FilterChain的执行过程

Filter中的过滤器链 FilterChain:由Tomcat引擎创建对象

作用:维护过滤器执行顺序

在这里插入图片描述

小结: Servlet中doGet方法参数 request, response对象, 由Tomcat引擎创建, 经过多个过滤器一层层传递

1.8、多个过滤器的先后执行顺序

web.xml配置

和配置文件的编写顺序决定运行的顺序,准确的说法是,根据mapping的顺序决定 (由上到下执行)

注解开发

注解开发没有配置文件的

按照类名的自然顺序决定: A-B-C

如果存在配置文件,配置文件优先

2、监听器Listener

2.1、Listener概述

监听器Listener 是监听某个组件变化的对象.

事件源是固定的,主要是request, session, servletcontext域对象

监听的是域对象变化
  ●对象的创建和销毁, 域对象中存储的数据变化

第一个维度划分:
  ●监听的域对象request, session, servletcontext

域对象监听器
requestServletRequestListener
sessionHttpSessionListener
servletcontextServletContextListener

第二个维度划分:
  ●监听的域对象的状态

2.2、 ServletContext监听器入门

用于监听 servletcontext域对象, 对象的创建和销毁, 域对象中存储的数据变化

实现步骤

●创建类实现监听器接口 ServletContextListener

●重写抽象方法

●注解方式配置 Listener

package com.bdit.liternce;

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

//监听器
@WebListener
public class ListernceServlet implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext域对象创建");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext域对象销毁");
    }
}

web.xml配置方式 Listener

<!--监视器-->
    <listener>
        <listener-class>com.bdit.liternce.ListernceServlet</listener-class>
    </listener>

2.3、监听器事件对象ServletContextEvent

ServletContextEvent: 是ServletContext域对象的事件对象, 此对象由tomcat引擎创建ServletContext

方法:
   ●ObjectgetSource()获取到被监听的事件源

   ●ServletContextgetServletContext()获取到被监听的事件源

小结:

   ●两个方法除了返回值外,功能实现是一致的, 设计目的为了通用性

   ●其他的监听器事件对象(HttpSessionEvent, ServletRequestEvent), 都有共同的方法getSource()

package com.bdit.liternce;

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

//监听器
@WebListener
public class ListernceServlet implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent ) {
        System.out.println("ServletContext域对象创建");

        ServletContext context = (ServletContext) servletContextEvent.getSource();
        System.out.println(context);
        ServletContext servletContext = servletContextEvent.getServletContext();
        System.out.println(servletContext);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent ) {
        System.out.println("ServletContext域对象销毁");
    }
}

2.4、注解版

package com.bdit.liternce;

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

//每次请求都会创建一个新的request对象;当响应结束后,立刻销毁request对象
@WebListener
public class ListernceServlet implements ServletContextListener {
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        ServletRequest servletRequest = servletRequestEvent.getServletRequest();
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        System.out.println("新的request对象创建了.......路径:" + httpServletRequest.getRequestURI());
    }

    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("request对象销毁了.......");
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值