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 对象被销毁了..."); } }
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) { } }
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 + '}'; } }
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. */ } }
注意:
end