day17_Listener与Filter

Posted Bruce

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了day17_Listener与Filter相关的知识,希望对你有一定的参考价值。

一、Listener监听器(了解)

Javaweb开发中的监听器,是用于监听web常见对象的。
? ? 例如web的常见对象有:ServletContext、HttpServletRequest、HttpSession
? ? 监听它们的创建与销毁属性变化session绑定javaBean

1、监听机制

? ? 事件:就是一个事情。
? ? 事件源:产生这个事情的源头。
? ? 监听器:用于监听指定的事件的对象。(关联事件和事件源)
? ? 注册监听:要想让监听器可以监听到事件产生,必须对其进行注册。

2、Javaweb开发中常见监听器

? 2.1、监听域对象的创建与销毁

? ? 若要监听ServletContext对象的创建与销毁? ? ? ?则需要写一个监听器类实现 ServletContextListener 接口
? ? 若要监听HttpSession对象的创建与销毁? ? ? ? ?则需要写一个监听器类实现 HttpSessionListener 接口
? ? 若要监听HttpServletRequest对象的创建与销毁? ?  则需要写一个监听器类实现 ServletRequestListener 接口

? 2.2、监听域对象的属性变化

? ? 若要监听ServletContext对象的属性变化? ? ? ?则需要写一个监听器类实现 ServletContextAttributeListener 接口
? ? 若要监听HttpSession对象的属性变化? ? ? ? ?则需要写一个监听器类实现 HttpSessionAttributeListener 接口
? ? 若要监听HttpServletRequest对象的属性变化? ?  则需要写一个监听器类实现 ServletRequestAttributeListener 接口

? 2.3、监听session绑定javaBean

? ? 若要监听javaBean对象是否绑定到了session域? ?  则需要写一个监听器类实现 HttpSessionBindingListener 接口
? ? 若要监听javaBean对象的活化与钝化? ? ? ?? ?则需要写一个监听器类实现 HttpSessionActivationListener 接口

3、监听器的快速入门

? 关于创建一个监听器的步骤:
? ? 1. 创建一个监听器类,实现指定的监听器接口。
? ? 2. 重写接口中的方法。
? ? 3. 在web.xml文件中对监听器进行注册。

? 3.1、关于域对象的创建与销毁的演示

? ? 1. ServletContext对象的创建与销毁
? ? ? ServletContext对象是在服务器启动时创建的,在服务器关闭时销毁的。

package com.itheima.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象被创建了"); // 服务器一启动,ServletContext对象就被创建了
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象被销毁了"); // 服务器一关闭,ServletContext对象就被销毁了
}
}

? ? 2. HttpSession对象的创建与销毁
? ? ? HttpSession session = request.getSession();
? ? ? Session的销毁方式:
? ? ? ? 1.默认超时30分钟后销毁
? ? ? ? 2.关闭服务器时销毁
? ? ? ? 3.调用invalidate()方法
? ? ? ? 4.setMaxInactiveInterval(int interval) 可以设置超时时间
? ? ? 问题:直接访问一个jsp页面时,是否会创建Session?
? ? ? ? 答:会创建,因为我们默认情况下是在jsp页面中直接使用Session内置对象的。

package com.itheima.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("HttpSession对象被创建了");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("HttpSession对象被销毁了");
}
}

  index.jsp

  <body>
<%
session.invalidate(); // 手动使session销毁
%>

</body>

? ? 3. HttpServletRequest对象的创建与销毁
? ? ? Request对象是发送请求时服务器就会去创建它,当响应产生时,request对象就会被销毁。

package com.itheima.listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("ServletRequest被销毁了");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("ServletRequest被创建 了");
}
}

? 3.2、演示Request域对象中的属性变化

? ? 在java的监听机制中,它的监听器中的方法都是有参数的,参数就是事件对象,而我们可以通过事件对象直接获取事件源。

package com.itheima.attributelistener;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
public class MyServletRequestListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
System.out.println("ServletRequest添加属性了");
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.out.println("ServletRequest移除属性了");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) { // 参数代表事件对象
System.out.println("ServletRequest替换属性了");
// srae.getServletRequest(); // 通过事件对象直接获取事件源
// System.out.println(srae.getName() + "\t" + srae.getValue()); // org.apache.catalina.ASYNC_SUPPORTED true
}
}

  index.jsp

  <body>
<%
// session.invalidate(); // 手动使session销毁
request.setAttribute("name", "tom");
request.setAttribute("name", "luna");
request.removeAttribute("name");
%>
</body>

? 3.3、演示session绑定javaBean

? ? 1.javaBean对象自动感知被绑定到session中
? ? ? HttpSessionBindingListener 这个接口是由javaBean实现的,并且不需要在web.xml文件中注册。

package com.itheima.domain;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class User implements HttpSessionBindingListener {
private String name;
private int 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 void valueBound(HttpSessionBindingEvent event) {
System.out.println("向session中绑定了一个user对象");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("从session中将user对象移除");
}
}

  index.jsp

  <body>
<%
// session.invalidate(); // 手动使session销毁
// request.setAttribute("name", "tom");
// request.setAttribute("name", "luna");
// request.removeAttribute("name");
User user = new User();
user.setName("luna");
user.setAge(25);
// 绑定到session
session.setAttribute("u", user);
// 解除绑定
session.removeAttribute("u");
%>
</body>

? ? 2.javabean对象可以活化或钝化到session中
? ? ? HttpSessionActivationListener,如果javaBean实现了这个接口,那么当我们正常关闭服务器时,session中的javaBean对象就会被钝化到我们指定的文件中。
? ? ? 当下一次再启动服务器,因为我们已经将对象写入到文件中,这时就会自动将javaBean对象活化到session中。

package com.itheima.domain;
import java.io.Serializable;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
public class User implements Serializable, HttpSessionBindingListener, HttpSessionActivationListener {
private String name;
private int 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 void valueBound(HttpSessionBindingEvent event) {
System.out.println("向session中绑定了一个user对象");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("从session中将user对象移除");
}
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("钝化");
}
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("活化");
}
}

  我们还需要个context.xml文件来配置钝化时存储的文件,在META-INF目录下创建一个context.xml文件,输入以下代码:

<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="it315"/>
</Manager>
</Context>

4、监听器的案例

? ? 4.1、案例1_定时销毁session

  1. 怎样可以将每一个创建的session全都保存起来呢?
    答:我们可以做一个HttpSessionListener,当session对象创建时,就将这个session对象装入到一个集合中,然后将集合List<HttpSession>保存到ServletContext域中。
  2. 怎样可以判断session过期了?
    答:在HttpSession中有一个方法public long getLastAccessedTime(),它可以得到session对象最后使用的时间。然后可以使用invalidate方法销毁

? ? 我们上面的操作需要使用任务调度功能。

以上是关于day17_Listener与Filter的主要内容,如果未能解决你的问题,请参考以下文章

java_day29_Servlet三大组件之监听器listener

servlet,filter,listener,intercepter区别

Listener监听器与Filter过滤器

JavaWeb之Filter&Listener

Android 调用组件 w/listener 或让 viewmodel 调用组件与片段通信

Filter,Servlet,Listener区别与联系