Filter+Listener(过滤器和拦截器)

Filter+Listener

Filter本意为”过滤“的含义,是JavaWeb的三大组件之一,三大组件为:Servlet、Filter、Listener。
过滤器是向 Web 应用程序的请求和响应处理添加功能的 Web 服务组件。
过滤器相当于浏览器与Web资源之间的一道过滤网,在访问资源之前通过一系列的过滤器对请求进行修改、判断以及拦截等,也可以对响应进行修改、判断以及拦截等。

在这里插入图片描述

使用方式

自定义类实现Filter接口并重写doFilter方法

public class LoginFilter implements Filter {

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

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //过滤操作
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpSession session = httpServletRequest.getSession();
        Object name = session.getAttribute("name");
        String servletPath = httpServletRequest.getServletPath();
        if (null == name && !"login".equalsIgnoreCase(servletPath)){
            System.out.println("拦截!!");
            servletRequest.getRequestDispatcher("login.jsp").forward(servletRequest,servletResponse);
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void destroy() {

    }
}

在web.xml文件中配置过滤器

	<!--配置过滤器-->
    <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>com.szx.filter.LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/main.jsp</url-pattern>
    </filter-mapping>

Filter接口

javax.servlet.Filter接口主要用于描述过滤器对象,可以对资源的请求和资源的响应操作进行筛选操作

void init(FilterConfig filterConfig) 实现过滤器的初始化操作
void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 执行过滤操作的功能
void destroy() 实现过滤器的销毁操作

public class LifeFilter implements Filter {
    public LifeFilter(){
        System.out.println("LifeFilter构造方法。。。");
    }
    @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("拦截器拦截一切数据。。。。");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("拦截器销毁。。。。");
    }
}
	<filter>
        <filter-name>LifeFilter</filter-name>
        <filter-class>com.szx.LifeFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LifeFilter</filter-name>
        <url-pattern>*.html</url-pattern>
    </filter-mapping>

FilterConfig接口

javax.servlet.FilterConfig接口主要用于描述过滤器的配置信息

String getFilterName() 获取过滤器的名字
String getInitParameter(String name) 获取指定的初始化参数信息
Enumeration getInitParameterNames() 获取所有的初始化操作名称
ServletContext getServletContext() 获取ServletContext对象

public class LifeFilter implements Filter {
    public LifeFilter(){
        System.out.println("LifeFilter构造方法。。。");
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化中。。。。。。");
        System.out.println(filterConfig.getFilterName());
        String initParameter = filterConfig.getInitParameter("name");
        System.out.println(initParameter);
        Enumeration<String> initParameterNames = filterConfig.getInitParameterNames();
        while (initParameterNames.hasMoreElements()){
            System.out.println(initParameterNames.nextElement());
        }
        System.out.println(filterConfig.getServletContext());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截器拦截一切数据。。。。");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("拦截器销毁。。。。");
    }
}
	<filter>
        <filter-name>LifeFilter</filter-name>
        <filter-class>com.szx.LifeFilter</filter-class>
        <init-param>
            <param-name>name</param-name>
            <param-value>admin</param-value>
        </init-param>
        <init-param>
            <param-name>password</param-name>
            <param-value>123</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>LifeFilter</filter-name>
        <url-pattern>*.html</url-pattern>
    </filter-mapping>

多个过滤器的使用

如果有多个过滤器都满足过滤的条件,则容器依据映射的先后顺序来调用各个过滤器

在这里插入图片描述

public class AFilter 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("第一道防线。。。");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("第一道防线返回。。。。");
    }

    @Override
    public void destroy() {

    }
}
public class BFilter 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("第二道防线。。。");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("第二道防线返回。。。。");
    }

    @Override
    public void destroy() {

    }
}
	<filter>
        <filter-name>AFilter</filter-name>
        <filter-class>com.szx.AFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AFilter</filter-name>
        <url-pattern>*.avi</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>BFilter</filter-name>
        <filter-class>com.szx.BFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>BFilter</filter-name>
        <url-pattern>*.avi</url-pattern>
    </filter-mapping>

在这里插入图片描述

过滤器优点

实现代码的“可插拔性”,即增加或减少某个功能模块,不会影响程序的正常执行。
可以将多个相同处理逻辑的模块集中写在过滤器里面,可实现重复利用、也方便代码的维护。

Listener监听器

Servlet规范中定义的一种特殊的组件,用来监听Servlet容器产生的事件并进行相应的处理。
容器产生的事件分类如下:
生命周期相关的事件。
属性状态相关的事件。
存值状态相关的事件。
底层原理是采用接口回调的方式实现。

javax.servlet.ServletRequestListener 监听request作用域的创建和销毁
javax.servlet.ServletRequestAttributeListener 监听request作用域的属性状态变化
javax.servlet.http.HttpSessionListener 监听session作用域的创建和销毁
javax.servlet.http.HttpSessionAttributeListener 监听session作用域的属性状态变化
javax.servlet.ServletContextListener 监听application作用域的创建和销毁
javax.servlet.ServletContextAttributeListener 监听application作用域的属性状态变化
javax.servlet.http.HttpSessionBindingListener 监听对象与session的绑定和解除
javax.servlet.http.HttpSessionActivationListener 监听session数值的钝化和活化

监听器详解

ServletRequestListener监听器

在ServletRequest创建和关闭时都会通知ServletRequestListener监听器。

void requestInitialized(ServletRequestEvent sre) 实现ServletRequest对象的初始化
void requestDestroyed(ServletRequestEvent sre) 实现ServletRequest对象的销毁

public class MyRequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("请求销毁。。。。");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("创建请求。。。。");
    }
}
	<listener>
        <listener-class>com.szx.demo03.MyRequestListener</listener-class>
    </listener>

ServletRequestAttributeListener监听器

向ServletRequest添加、删除或者替换一个属性的时候,将会通知ServletRequestAttributeListener监听器。

void attributeAdded(ServletRequestAttributeEvent srae) 增加属性时触发
void attributeReplaced(ServletRequestAttributeEvent srae) 修改属性时触发
void attributeRemoved(ServletRequestAttributeEvent srae) 删除属性时触发

public class MyRequestArributeListener implements ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("增加属性。。。" + servletRequestAttributeEvent.getName());
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("属性删除。。。" + servletRequestAttributeEvent.getName() + "被删除");
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("修改属性。。。" + servletRequestAttributeEvent.getName());
    }
}
	<listener>
        <listener-class>com.szx.demo03.MyRequestArributeListener</listener-class>
    </listener>
<%
    request.setAttribute("name","guanyu");
    request.setAttribute("name","zhangfei");
    request.removeAttribute("name");
%>

监听器

当一个HttpSession刚被创建或者失效(invalidate)的时候,将会通知HttpSessionListener监听器。

void sessionCreated(HttpSessionEvent se) 当一个HttpSession对象被创建时会调用这个方法
void sessionDestroyed(HttpSessionEvent se) 当一个HttpSession超时或者调用HttpSession的
invalidate() 方法让它销毁时,将会调用这个方法

public class MyHttpSessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("创建");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("销毁");
    }
}
	<listener>
        <listener-class>com.szx.demo03.MyHttpSessionListener</listener-class>
    </listener>

HttpSessionAttributeListener监听器

HttpSession中添加、删除或者替换一个属性的时候,将会通知HttpSessionAttributeListener监听器。

void attributeAdded(HttpSessionBindingEvent se) 当往会话中加入一个属性的时候会调用这个方法
void attributeRemoved(HttpSessionBindingEvent se) 当从会话中删除一个属性的时候会调用这个方法
void attributeReplaced(HttpSessionBindingEvent se) 当改变会话中的属性的时候会调用这个方法

public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("增加session" + httpSessionBindingEvent.getName());
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("删除session" + httpSessionBindingEvent.getName());
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("修改session" + httpSessionBindingEvent.getName());
    }
}
	<listener>
        <listener-class>com.szx.demo03.MyHttpSessionAttributeListener</listener-class>
    </listener>
<%
    session.setAttribute("name","zhugeliang");
    session.setAttribute("name","guanyu");
    session.removeAttribute("name");
%>

ServletContextListener监听器

在ServletContext创建和关闭时都会通知ServletContextListener监听器。

void contextInitialized(ServletContextEvent sce) 当ServletContext创建的时候,将会调用这个方法
void contextDestroyed(ServletContextEvent sce) 当ServletContext销毁的时候(例如关闭应用服务器或者重新加载应用),将会调用这个方法

public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("创建。。。。");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("销毁。。。。");
    }
}
	<listener>
        <listener-class>com.szx.demo03.MyServletContextListener</listener-class>
    </listener>

ServletContextAttributeListener监听器

向ServletContext添加、删除或者替换一个属性的时候,将会通知ServletContextAttributesListener监听器

void attributeAdded(ServletContextAttributeEvent scae) 往ServletContext中加入一个属性的时候触发
void attributeRemoved(ServletContextAttributeEvent scae) 从ServletContext中删除一个属性的时候触发
void attributeReplaced(ServletContextAttributeEvent scae) 改变ServletContext中属性的时候触发

public class MyServletContextAttributeListener implements ServletContextAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("增加  " + servletContextAttributeEvent.getName());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("删除  " + servletContextAttributeEvent.getName());
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("修改  " + servletContextAttributeEvent.getName());
    }
}
	<listener>
        <listener-class>com.szx.demo03.MyServletContextAttributeListener</listener-class>
    </listener>
<%
    application.setAttribute("name","dayu");
    application.setAttribute("name","wangjian");
    application.removeAttribute("name");
%>

HttpSessionBindingListener监听器

HttpSession中绑定和解除绑定时,将会通知HttpSessionListener监听器。

void valueBound(HttpSessionBindingEvent event) 有对象绑定时调用该方法
void valueUnbound(HttpSessionBindingEvent event) 有对象解除绑定时调用该方法

public class Person implements HttpSessionBindingListener {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("对象绑定session。。。");
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("对象解绑session。。。");
    }
}
<%
    Person person = new Person("zhangfei",20);
    session.setAttribute("person",person);
    session.removeAttribute("person");
%>

HttpSessionActivationListener监听器

当有session数值的钝化和活化操作时,将会通知HttpSessionActivationListener监听器。

void sessionWillPassivate(HttpSessionEvent se) 有钝化操作时调用该方法
void sessionDidActivate(HttpSessionEvent se) 有活化操作时调用该方法

public class Student implements Serializable, HttpSessionActivationListener {
    private String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("执行钝化。。。。");
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("执行活化。。。。");
    }
}
context.xml

<Manager className="org.apache.catalina.session.PersistentManager"
saveOnRestart="true">
<!-- 配置文件存放的路径信息,可以自由指定 -->
  <Store className="org.apache.catalina.session.FileStore"
directory="C:\session"/>
</Manager>
<%
    Student student = new Student("zhangfei");
    session.setAttribute("student",student);
%>

自定义类实现监听器接口并重写相关的方法。

public class OnlineUser implements HttpSessionListener, ServletContextListener {

    //声明一个ServletContext类型引用,全局变量,用来记录当前在线用户数量,通过属性记录
    private ServletContext servletContext = null;

    /**
     * 初始化ServletContext
     * @param servletContextEvent
     */
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        servletContext = servletContextEvent.getServletContext();
    }

    /**
     * 销毁ServletContext
     * @param servletContextEvent
     */
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        servletContext = null;
    }

    /**
     * 当新创建一个HttpSession对象时
     * @param httpSessionEvent
     */
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("用户上线。。。。");
        Object count = servletContext.getAttribute("count");
        //若当前用户为的一个用户,则将全局对象中属性值设置为1即可
        if (null == count){
            servletContext.setAttribute("count",1);
        }
        //若当前用户不是第一个,则将全局对象原有数据取出 +1 后写入
           else {
               Integer integer = (Integer)count;
               integer++;
               servletContext.setAttribute("count",integer);
        }
        System.out.println("当前在线用户数量为:" + servletContext.getAttribute("count"));
    }

    /**
     * 当一个HttpSession被销毁时(过期或者调用了invalidate()方法)
     * @param httpSessionEvent
     */
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("用户下线。。。。");
    }
}
	<listener>
        <listener-class>com.szx.demo03.OnlineUser</listener-class>
    </listener>
<h1>当前在线用户数为:${applicationScope.count}</h1>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值