java web Filter 过滤器和Listener 监听器

Filter 过滤器

  • 在程序中访问服务器资源时,当一个请求到来,服务器首先判断是否有过滤器与请求资源相关联,如果有,过滤器可以将请求拦截下来,完成一些的功能,再由过滤器决定是否交给请求资源。如果没有则像之前那样直接请求资源了。响应也类似的!
  • 过滤器一般用于完成通用的操作,例如:登录验证、统一编码处理、敏感字符过滤器~~~
  • Filter 是一个接口。如果想实现过滤器的功能,必须实现接口!
  • 核心方法
返回值方法名作用
voidinit(FilterConfig config)初始方法
voiddoFilter(ServletRequest request,ServletResponse response,FilterChain chain)初始方法
voiddestroy()初始方法
  • 配置方式
    • 注解方式
    • 配置文件

FilterChain

  • FilterChain 是一个接口,代表过滤器链对象。由Servlet容器提供实现类对象。直接使用即可。
  • 过滤器可以定义多个,就会组成过滤器链。
  • 核心方法
返回值方法名作用
voiddoFilter(ServletRequest request,ServletResponse response)初始方法

如果有多个过滤器,在第一个过滤器中调用下一个过滤器,依次类推。直到到达最终访问资源。
如果只有一个过滤器,放行时,就会直接到达最终访问资源。

过滤器使用

  • 需求说明:通过Filter过滤器解决多个资源写出中文乱码的问题。
  • 最终目的:通过本需求,最终掌握Filter过滤器的使用。
    新建Filter包新建newFilter类
package com.fliter;

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

//注解方式配置,括号里面是 需要过滤的路径
@WebFilter("/newServlet")
public class newFilter implements Filter {

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

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("我是newFilter我执行了~~~~~~~~~~~~");

        //处理乱码
        servletResponse.setContentType("text/html;charset=UTF-8");

        //放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

过滤器使用细节

  • 配置方式
    • 注解方式 @WebFilter(拦截路径)
    • 配置文件方式(复杂)
<?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>newFilter</filter-name>
        <filter-class>com.fliter.newFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>newFilter</filter-name>
        <url-pattern>/newServlet</url-pattern>
    </filter-mapping>
</web-app>
  • 多个过滤器使用顺序
<?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>newFilter</filter-name>
        <filter-class>com.fliter.newFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>newFilter</filter-name>
        <url-pattern>/newServlet</url-pattern>
    </filter-mapping>

    <!--  第二个执行  -->
    <filter>
        <filter-name>filterDemo01</filter-name>
        <filter-class>com.fliter.filterDemo01</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filterDemo01</filter-name>
        <url-pattern>/newServlet</url-pattern>
    </filter-mapping>
</web-app>

过滤器生命周期

  • 创建:当应用加载实例化对象并执行init初始化方法。
  • 服务:对象提供服务的过程,执行doFilter方法。
  • 销毁:当应用卸载时或服务器停止时对象销毁。执行destroy方法。
package com.fliter;

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

//注解方式配置,括号里面是 需要过滤的路径
//@WebFilter("/newServlet")
public class newFilter implements Filter {

    // 当应用加载实例化对象
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("对象初始化成功了!");
    }

    // 对象提供服务的过程
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("我是newFilter我执行了~~~~~~~~~~~~");

        //处理乱码
        servletResponse.setContentType("text/html;charset=UTF-8");

        //放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    //当应用卸载时或服务器停止时对象销毁
    @Override
    public void destroy() {
        System.out.println("对象销毁了!");
    }
}

FilterConfig

  • FilterConfig是一个接口。代表过滤器的配置对象,可以加载一些初始化参数。
  • 核心方法
返回值方法名作用
StringgetFilterName()获取过滤器对象名称
StringgetInitParameter(String key)根据key获取value
Enumeration<String>getInitParameterNames()获取所有参数的key
StringgetFilterName()获取过滤器对象名称
ServletContextgetServletContext()获取应用上下文对象
  • 首先在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">

    <filter>
        <filter-name>newFilter</filter-name>
        <filter-class>com.fliter.newFilter</filter-class>
        
        <!--  配置名称  -->
        <init-param>
            <param-name>username</param-name>
            <param-value>zhangsan</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>newFilter</filter-name>
        <url-pattern>/newServlet</url-pattern>
    </filter-mapping>
</web-app>
  • newFilter里接收
package com.fliter;

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

//注解方式配置,括号里面是 需要过滤的路径
//@WebFilter("/newServlet")
public class newFilter implements Filter {

    // 当应用加载实例化对象
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("对象初始化成功了!");

        // 获取过滤器名称
        String filterName = filterConfig.getFilterName();
        System.out.println(filterName);

        // 根据name获取value
        String username = filterConfig.getInitParameter("username");
        System.out.println(username);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("我是newFilter我执行了~~~~~~~~~~~~");
    }

    @Override
    public void destroy() {
        System.out.println("对象销毁了!");
    }
}

过滤器五种拦截行为

  • Filter过滤器默认拦截的是请求,但是在实际开发中,我们还有请求转发和请求包含,以及由服务器触发调用的全局错误页面。默认情况下过滤器是不参与过滤的,要想使用,就需要我们配置。
<?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>newFilter</filter-name>
        <filter-class>com.fliter.newFilter</filter-class>
        <!--配置开启异步支持,当dispatcher配置ASYNC时,需要配置此行-->
        <async-supported>true</async-supported>
    </filter>

    <filter-mapping>
        <filter-name>newFilter</filter-name>
        <!--<url-pattern>/error.jsp</url-pattern>-->
        <url-pattern>/index.jsp</url-pattern>
        <!--过滤请求:默认值。-->
        <dispatcher>REQUEST</dispatcher>
        <!--过滤全局错误页面:当由服务器调用全局错误页面时,过滤器工作-->
        <dispatcher>ERROR</dispatcher>
        <!--过滤请求转发:当请求转发时,过滤器工作。-->
        <dispatcher>FORWARD</dispatcher>
        <!--过滤请求包含:当请求包含时,过滤器工作。它只能过滤动态包含,jsp的include指令是静态包含,过滤器不会起作用-->
        <dispatcher>INCLUDE</dispatcher>
        <!--过滤异步类型,它要求我们在filter标签中配置开启异步支持-->
        <dispatcher>ASYNC</dispatcher>
    </filter-mapping>
    
    <!--配置全局错误页面-->
    <error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>/error.jsp</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/error.jsp</location>
    </error-page>
</web-app>

Listener 监听器

  • 观察者设计模式,所有的监听器都是基于观察者设计模式的!

  • 三个组成部分

    • 事件源:触发事件的对象
    • 事件:触发的动作,封装了事件源
    • 监听器:当事件源触发事件后,可以完成功能
  • 在程序当中,我们可以对:对象的创建销毁、域对象中属性的变化、会话相关内容进行监听。

  • Servlet 规范中共计 8 个监听器,监听器都是以接口形式提供,具体功能需要我们自己来完成。

监听器对象的监听器

  • ServletContextListener:用于监听 ServletContext 对象的创建和销毁
  • 核心方法
返回值方法名作用
voidcontextInitialized(ServletContextEvent sce)对象创建时执行该方法
voidcontextDestroyed(ServletContextEvent sce)对象销毁时执行该方法
参数:ServletContextEvent 代表事件对象 事件对象封装了事件源,也就是ServletContext 真正的事件指的是创建或销毁ServletContext对象的操作
  • HttpSessionListener:用于监听 HttpSession 对象的创建和销毁
  • 核心方法
返回值方法名作用
voidsessionCreated(HttpSessionEvent se)对象创建时执行该方法
voidsessionDestroyed(HttpSessionEvent se)对象销毁时执行该方法
参数:HttpSessionEvent 代表事件对象 事件对象封装了事件源,也就是HttpSession 真正的事件指的是创建或销毁HttpSession对象的操作
  • ServletRequestListener:用于监听 ServletRequest 对象的创建和销毁
  • 核心方法
返回值方法名作用
voidrequestInitialized(ServletRequestEvent sre)对象创建时执行该方法
voidrequestDestroyed(ServletRequestEvent sre)对象销毁时执行该方法
参数:ServletRequestEvent 代表事件对象 事件对象封装了事件源,也就是ServletRequest 真正的事件指的是创建或销毁ServletRequest对象的操作

监听域对象属性变化的监听器

  • ServletContextAttributeListener:用于监听 ServletContext 应用域中属性的变化
  • 核心方法
返回值方法名作用
voidattributeAdded(ServletContextAttributeEvent scae)域中添加属性时执行该方法
voidattributeRemoved(ServletContextAttributeEvent scae)域中移除属性时执行该方法
voidattributeReplaced(ServletContextAttributeEvent scae)域中替换属性时执行该方法
参数:ServletContextAttributeListener 代表事件对象 事件对象封装了事件源,也就是ServletContext 真正的事件指的是添加、移除、替换应用域中属性的操作
  • HttpSessionAttributeListener:用于监听 HttpSession 应用域中属性的变化
  • 核心方法
返回值方法名作用
voidattributeAdded(HttpSessionBindingEvent se)域中添加属性时执行该方法
voidattributeRemoved(HttpSessionBindingEvent se)域中移除属性时执行该方法
voidattributeReplaced(HttpSessionBindingEvent se)域中替换属性时执行该方法
参数:HttpSessionBindingEvent 代表事件对象 事件对象封装了事件源,也就是HttpSession 真正的事件指的是添加、移除、替换应用域中属性的操作
  • ServletRequestAttributeListener:用于监听 ServletRequest 应用域中属性的变化
  • 核心方法
返回值方法名作用
voidattributeAdded(ServletRequestAttributeEvent se)域中添加属性时执行该方法
voidattributeRemoved(ServletRequestAttributeEvent se)域中移除属性时执行该方法
voidattributeReplaced(ServletRequestAttributeEvent se)域中替换属性时执行该方法
参数:ServletRequestAttributeEvent 代表事件对象 事件对象封装了事件源,也就是ServletRequest 真正的事件指的是添加、移除、替换应用域中属性的操作

监听会话相关的感知型监听器

  • HttpSessionBindingListener:用于感知对象和会话域绑定的监听器
  • 核心方法
返回值方法名作用
voidvalueBound(HttpSessionBindingEvent event)数据添加到会话域中(绑定)时执行该方法
voidvalueUnbound(HttpSessionBindingEvent event)数据从会话域中移除(解绑)时执行该方法
参数:HttpSessionBindingEvent 代表事件对象 事件对象封装了事件源,也就是HttpSession 真正的事件指的是添加、移除会话域中数据的操作
  • HttpSessionActivationListener:用于感知会话域中对象钝化和活化的监听器
  • 核心方法
返回值方法名作用
voidsessionWillPassivate(HttpSessionEvent se)会话域中数据钝化时执行该方法
voidsessionDidActivate(HttpSessionEvent se)会话域中数据活化时执行该方法
参数:HttpSessionEvent 代表事件对象 事件对象封装了事件源,也就是HttpSession 真正的事件指的是会话域中数据钝化、活化的操作

监听器的使用

  • 监听对象的
    • ServletContextListener
    • HttpSessionListener
    • ServletRequestListener
  • 监听属性变化的
    • ServletContextAttributeListener
    • HttpSessionAttributeListener
    • ServletRequestAttributeListener
  • 会话相关的感知型
    • HttpSessionBindingListener
    • HttpSessionActivationListener

监听ServletContextListener

新建一个listener包新建newListener

package com.listener;

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

// 注解配置
@WebListener
public class newListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("监听器创建了!!!!!!");

        // 获取对象
        ServletContext servletContext = sce.getServletContext();
        System.out.println(servletContext);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("监听器销毁了!!!!!!");
    }
}

监听ServletContextAttributeListener

package com.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;

// 注解配置
@WebListener
public class newListener implements ServletContextAttributeListener {

    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
        System.out.println("监听到了属性的添加。。。");

        // 获取应用域对象
        ServletContext servletContext = scae.getServletContext();

        //获取属性
        Object username = servletContext.getAttribute("username");
        System.out.println(username);
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {
        System.out.println("监听到了属性的替换。。。");

        // 获取应用域对象
        ServletContext servletContext = scae.getServletContext();

        //获取属性
        Object username = servletContext.getAttribute("username");
        System.out.println(username);
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
        System.out.println("监听到了属性的移除。。。");

        // 获取应用域对象
        ServletContext servletContext = scae.getServletContext();

        //获取属性
        Object username = servletContext.getAttribute("username");
        System.out.println(username);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值