Javaweb三大组件-过滤器、监听器

1. 过滤器 【filter】

作用:

  对单个获取多个servlet起到增强【advice】的作用。

  用于在所有的servlet执行前,做一些预处理。例如:做编码处理,

    访问量统计【servletContext = application】,request.getServletContext()

    获取user 的ip:request.getRemoteAddr();

特性:

  单例,线程不安全

创建:

  实现javax.servlet.Filter接口:

package cn.getword.filter;

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

public class EncodingFilter implements Filter {
    private String charset;
    /**
     * 初始化方法,只执行一次
     * 配置过滤器参数
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init encoding filter...");
        charset = filterConfig.getInitParameter("charset");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        servletRequest.setCharacterEncoding(charset);
        System.out.println("before");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("after");
    }

    /**
     * 销毁方法,只执行一次
     */
    @Override
    public void destroy() {
        System.out.println("destroy encoding filter");
    }
}

 

 

  设置编码:ServletRequest是一个接口,setCharacterEncoding方法, servletRequest参数是HTTPServletRequest类的实例,可以不用强转

 

  配置:

    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>cn.getword.filter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>

  不仅能过滤servlet,而且还能过滤jsp文件,还有静态资源文件.

  过滤所有servlet:*.do  ,过滤所有.do的servlet

 

生命周期:

  在服务器启动时,进行实例化。单例

  每次过滤,执行一次doFilter方法

多个过滤器共同生效:

  /index.do  

  *.do

  执行顺序:注册的顺序【web.xml】,注解也有顺序。过滤器链,最后一个过滤器调用servlet的方法

    转发:不会被过滤器过滤。

  重定向:再次请求,会被过滤。

 

2. 监听器  Listener

  含义:用来监听其他对象的状态变或者触发的事件。

  特性:单例,线程不安全

 

  分类:针对servlet域对象。

  • ServletRequest
  • HttpSession
  • ServletContext  = application【jsp】 = applicationScope【EL】

 

  针对域对象,有8个监听接口,监听6个事件。

对象  监听接口 监听事件 说明
针对ServletContext ServletContextListener
ServletContextEvent
监听创建和销毁事件
ServletContextAttributeListener
ServletContextAttributeEvent
监听属性变化
针对HttpServletRequest ServletRequestListener 省略  
ServletRequestAttributeListener 省略  
HttpSession HttpSessionListener HttpSessionEvent  
HttpSessionAttributeListener HttpSessionBindingEvent  
HttpSessionBindingListener 绑定特定对象【实现该接口的对象】,触发事件  
HttpSessionActivationListener 了解  

 

  监听创建和销毁:ServletContextListener, ServletRequestListener, HttpSessionListener

 

  创建:

实现接口

  ServletContextListener:监听创建、销毁

package cn.getword.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class AServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("application 对象被创建了...");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("application 对象被销毁了...");
    }
}
View Code

 

  ServletContextAttributeListener:监听属性变化【增删改查】,

e.g application.setAttribute(key, value);【jsp】   

   request.getServletContext().setAttribute(key, value); 【servlet】

package cn.getword.listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

public class AServletContextAttributeListener implements ServletContextAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {

    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {

    }
}
View Code

 

 

HttpSessionActivation: 不需要再web.xml中配置。【了解】

  作用:监听session的钝化、活化

  钝化:session序列化到硬盘中

  活化:session反序列化到内存中

  如果该类实现HttpSessionActivation和Serializable接口,就会和session一起写入硬盘中

  如果没有实现Serilizable接口,钝化时就会被剔除

 

HttpSessionBindingListener:【不需要配置】

  作用:实现该接口的对象,一旦被绑定【setAttribute】或者移除【removeAttribute】session对象中,就会触发事件。

e.g session.setAttribute(key, new HttpSessionBindingListener())

 

 

  配置:

    <listener>
        <listener-class>cn.getword.listener.AServletContextListener</listener-class>
    </listener>

 

多个监听器加载顺序也是和配置顺序一样

 

 3.三大组件的启动顺序

listener>filter>Servlet

 

 

 

 

   应用:统计在线人数

设置session过期时间:

    <!--设置session过期时间-->
    <session-config>   <!--分钟为单位-->
        <session-timeout>1</session-timeout>
    </session-config>

  当session过期后,不会立刻被清理掉,而是需要等待垃圾回收机制【GC】自动回收,才能触发session销毁事件。

 

package cn.getword.model;

import java.util.Date;

public class OnlineUser {
    private Integer id;
    private String username;
    private String ip;
    private String area;
    private String time;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    @Override
    public String toString() {
        return "OnlineUser{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", ip='" + ip + '\'' +
                ", area='" + area + '\'' +
                ", time=" + time +
                '}';
    }
}
OnlineUser.java

 

 

package cn.getword.listener;

import cn.getword.domain.User;
import cn.getword.model.OnlineUser;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;
import java.util.ArrayList;
import java.util.List;

/**
 * 在线user信息,保存
 * 使用application对象保存user信息
 */
@WebListener()
public class OnlineSessionListener implements ServletContextListener,
        HttpSessionListener, HttpSessionAttributeListener {
    public static List<OnlineUser> onlineUsers = new ArrayList<OnlineUser>();

    // Public constructor is required by servlet spec
    public OnlineSessionListener() {
    }

    // -------------------------------------------------------
    // ServletContextListener implementation
    // -------------------------------------------------------
    public void contextInitialized(ServletContextEvent sce) {
      /* This method is called when the servlet context is
         initialized(when the Web application is deployed). 
         You can initialize servlet context related data here.
      */
    }

    public void contextDestroyed(ServletContextEvent sce) {
      /* This method is invoked when the Servlet Context 
         (the Web application) is undeployed or 
         Application Server shuts down.
      */
    }

    // -------------------------------------------------------
    // HttpSessionListener implementation
    // -------------------------------------------------------
    public void sessionCreated(HttpSessionEvent se) {
      /* Session is created. */
    }

    /**
     * session注销事件,如果session注销前,用户登录了,则清除该用户
     *
     * @param se
     */
    public void sessionDestroyed(HttpSessionEvent se) {
        se.getSession().invalidate();
        OnlineUser user = (OnlineUser) se.getSession().getAttribute("user");
        if (user != null) {
            System.out.println(user.getUsername() + "被注销了");
        }
    }

    // -------------------------------------------------------
    // session属性添加事件:如果添加了user属性,则将该用户添加到在线名单中
    // -------------------------------------------------------

    public void attributeAdded(HttpSessionBindingEvent sbe) {
      /* This method is called when an attribute 
         is added to a session.
      */
        if ("user".equals(sbe.getName())) { //session添加了属性user
            System.out.println("add a user" + sbe.getValue());
            onlineUsers.add((OnlineUser) sbe.getValue());
        }

    }

    /**
     * 属性移除事件:如果移除了user属性,则将该user从在线列表中删除
     *
     * @param sbe
     */
    public void attributeRemoved(HttpSessionBindingEvent sbe) {
      /* This method is called when an attribute
         is removed from a session.
      */
        if ("user".equals(sbe.getName())) { //session添加了属性user
            System.out.println("remove a user" + sbe.getValue());
            onlineUsers.remove((OnlineUser) sbe.getValue());
        }
    }

    public void attributeReplaced(HttpSessionBindingEvent sbe) {
      /* This method is invoked when an attibute
         is replaced in a session.
      */
    }
}
OnlineSessionListener.java

 

 

注意:

 

end

posted @ 2018-09-12 10:48  fight139  阅读(653)  评论(0编辑  收藏  举报