Servlet之监听器

1、java事件监听机制

   * 1.java的事件监听机制涉及到三个组件:事件源、事件监听器、事件对象
   * 2.当事件源上发生操作时,它将会调用事件监听器的一个方法,并在调用这个方法时,会传递事件对象过来。
   * 3事件监听器由开发人员编写,开发人员在事件监听器中,通过事件对象可以拿到事件源,从而对事件源上的操作进行处理。
代码片段:

<span style="font-family:KaiTi_GB2312;font-size:14px;">//观察者设计模式(observer设计模式)

//事件源
class Person{
	private PersonListener listener;
	public void registerListener(PersonListener listener){
		this.listener = listener;
	}
	public void run(){
		if(listener!=null){
			Even even = new Even(this);
			this.listener.dorun(even);
		}
		System.out.println("runn!!");
	}
	public void eat(){
		if(listener!=null){
			Even e = new Even(this);
			this.listener.doeat(e);
		}
		System.out.println("eat!!");
	}
}
//事件监听器
interface PersonListener{
	public void dorun(Even even);
	public void doeat(Even even);
}
//事件对象(封装事件源)
class Even{
	private Person person;
	public Even() {
		super();
	}

	public Even(Person person) {
		super();
		this.person = person;
	}

	public Person getPerson() {
		return person;
	}

	public void setPerson(Person person) {
		this.person = person;
	}
}

public class Demo3 {

	public static void main(String[] args) {
	
		Person p = new Person();
		p.registerListener(new MyListener1());
		p.eat();
		p.run();
	}
}

class MyListener1 implements PersonListener{

	public void doeat(Even even) {
		System.out.println(even.getPerson()+"你天天吃,你就知道吃,你猪啊!!");
	}

	public void dorun(Even even) {
		System.out.println(even.getPerson()+"你吃完就跑,有病!!");
		
	}	
}
</span><span style="font-family:KaiTi_GB2312;font-size:14px;">
</span>


2、Servle监听器
    在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为ServletContext, HttpSessionServletRequest 这三个域对象。 l
    Servlet规范针对这三个对象上的操作,又把这多种类型的监听器划分为三种类型。
监听三个域对象创建和销毁的事件监听器
监听域对象中属性的增加和删除的事件监听器
监听绑定到 HttpSession 域中的某个对象的状态的事件监听器。(查看API文档)

2.1--[编写Servlet监听器]
    和编写其它事件监听器一样,编写servlet监听器也需要实现一个特定的接口,并针对相应动作覆盖接口中的相应方法。
    和其它事件监听器略有不同的是,servlet监听器的注册不是直接注册在事件源上,而是由WEB容器负责注册,开发人员只需在web.xml文件中使用<listener>标签配置好监听器,web容器就会自动把监听器注册到事件源中。一个web.xml 文件中可以配置多个Servlet 事件监听器,web 服务器按照它们在web.xml 文件中的注册顺序来加载和注册这些Serlvet 事件监听器。


2.2--[监听三个域对象域对象创建和销毁]
监听servletContext域对象创建和销毁:
ServletContextListener 接口用于监听ServletContext 对象的创建和销毁事件。
当ServletContext 对象被创建时,激发contextInitialized (ServletContextEventsce)方法
当ServletContext 对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法。
•创建:服务器启动针对每一个web应用创建servletcontext
•销毁:服务器关闭前先关闭代表每一个web应用的servletContext

监听HttpSession域对象创建和销毁
HttpSessionListener接口用于监听HttpSession的创建和销毁
创建一个Session时,sessionCreated(HttpSessionEvent se) 方法将会被调用。
销毁一个Session时,sessionDestroyed (HttpSessionEvent se) 方法将会被调用。
•创建:用户每一次访问时,服务器创建session
•销毁:如果用户的session 30分钟没有使用,服务器就会销毁session,我们在web.xml里面也可以配置session失效时间

监听HttpRequest域对象创建和销毁
ServletRequestListener 接口用于监听ServletRequest 对象的创建和销毁。
Request 对象被创建时,监听器的requestInitialized方法将会被调用。
Request对象被销毁时,监听器的requestDestroyed方法将会被调用。
•创建:用户每一次访问,都会创建一个reqeust
•销毁:当前访问结束,request对象就会销毁

2.3--[监听三个域对象属性变化]
     Servlet规范定义了监听ServletContext, HttpSession,HttpServletRequest 这三个对象中的属性变更信息事件的监听器。
这三个监听器接口分别是ServletContextAttributeListener,HttpSessionAttributeListener ServletRequestAttributeListener
这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件,同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同。attributeAdded方法,attributeRemoved方法,attributeReplaced方法。


2.4--[感知 Session绑定的事件监听器]
     保存在Session 域中的对象可以有多种状态:绑定到  Session中;从 Session域中解除绑定;随 Session对象持久化到一个存储设备中;随 Session 对象从一个存储设备中恢复。Servlet 规范中定义了两个特殊的监听器接口来帮助 JavaBean 对象了解自己在 Session域中的这些状态:HttpSessionBindingListener接口和HttpSessionActivationListener接口,实现这两个接口的类不需要 web.xml文件中进行注册,因为他们事件源和监听器是同一对象。


HttpSessionBindingListener接口
实现了HttpSessionBindingListener接口的JavaBean 对象可以感知自己被绑定到Session 中和从Session 中删除的事件
当对象被绑定到HttpSession 对象中时,web 服务器调用该对象的  voidvalueBound(HttpSessionBindingEvent event)方法
当对象从HttpSession 对象中解除绑定时,web 服务器调用该对象的voidvalueUnbound(HttpSessionBindingEvent event)方法


HttpSessionActivationListener接口
实现了HttpSessionActivationListener接口的JavaBean 对象可以感知自己被活化和钝化的事件
当绑定到HttpSession 对象中的对象将要随HttpSession 对象被钝化之前,web 服务器调用如下方法sessionWillPassivate(HttpSessionBindingEventevent) 方法
当绑定到HttpSession 对象中的对象将要随HttpSession 对象被活化之后,web 服务器调用该对象的voidsessionDidActive(HttpSessionBindingEvent event)方法

3、简单应用之代码片段

3.1--[l统计当前在线人数]

<span style="font-size:14px;">public class CountNumListener implements HttpSessionListener {

	public void sessionCreated(HttpSessionEvent se) {
		ServletContext context = se.getSession().getServletContext();
		Integer count = (Integer) context.getAttribute("count");
		if(count==null){
			count = 1;
			context.setAttribute("count", count);
		}else{
			count++;
			context.setAttribute("count", count);
		}
	}

	public void sessionDestroyed(HttpSessionEvent se) {
		ServletContext context = se.getSession().getServletContext();
		Integer count = (Integer) context.getAttribute("count");
		count--;
		context.setAttribute("count", count);

	}
}</span><span style="font-size:24px;font-weight: bold;">
</span>
3.2--[l自定义session扫描器]

<span style="font-size:14px;">public class SessionScanner implements HttpSessionListener,ServletContextListener {
	//Collections这个集合工具类生成的集合是线程安全的。
	private List<HttpSession> list = Collections.synchronizedList(new LinkedList<HttpSession>());
	private Object lock = new Object();
	public void contextInitialized(ServletContextEvent sce) {
		
		Timer timer = new Timer();
		timer.schedule(new MyTask(list,lock), 0, 30*1000);
	}
	
	public void sessionCreated(HttpSessionEvent se) {
		HttpSession session = se.getSession();
		System.out.println(session + "被创建了!!");
		synchronized (lock) {  //锁旗标
			list.add(session);
		}
	}
	public void sessionDestroyed(HttpSessionEvent se) {
		System.out.println(se.getSession() + "被销毁了");
	}

	public void contextDestroyed(ServletContextEvent sce) {
		// TODO Auto-generated method stub
	}
}

class MyTask extends TimerTask{

	private List list;
	private Object lock;
	public MyTask(List list,Object lock){
		this.list = list;
		this.lock = lock;
	}
	@Override
	public void run() {
		System.out.println("定时器执行!!");
		synchronized (this.lock) {
			ListIterator it = list.listIterator();
			while(it.hasNext()){
				HttpSession session = (HttpSession) it.next();
				if((System.currentTimeMillis()-session.getLastAccessedTime())>30*1000){
					session.invalidate();
					//list.remove(session);  //并发修改异常
					it.remove();
				}
			}
		}
	}
}

/*class MyList{
	
	Object arr[] = new Object[10];
	public void add(Object obj){  //session
		if(arr[0]==null){
			
			arr[0] = obj;
		}
		
	}
}*/</span><span style="font-size:24px;font-weight: bold;">
</span>

3.3--[踢用户]

<span style="font-size:14px;">public class UserListener implements HttpSessionAttributeListener {

	public void attributeAdded(HttpSessionBindingEvent se) {
		
		Map map = (Map) se.getSession().getServletContext().getAttribute("map");
		if(map==null){
			map = new HashMap();
			se.getSession().getServletContext().setAttribute("map", map);
		}
		
		Object object = se.getValue();
		if(object instanceof User){
			User user = (User) object;
			map.put(user.getUsername(), se.getSession());
		}
		
	}

	public void attributeRemoved(HttpSessionBindingEvent se) {
		......		
	}

	public void attributeReplaced(HttpSessionBindingEvent se) {
		......		
	}
}

public class KickServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		String username = request.getParameter("username");
		username = new String(username.getBytes("iso8859-1"),"UTF-8");
		
		Map map = (Map) this.getServletContext().getAttribute("map");
		HttpSession session = (HttpSession) map.get(username);
		if(session!=null){
			session.invalidate();
			map.remove(username);
		}
		
		response.sendRedirect("/kick/listuser.jsp");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}</span><pre name="code" class="java">
public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		request.setCharacterEncoding("UTF-8");
		
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		
		User user = new User();
		user.setPassword(password);
		user.setUsername(username);
		
		request.getSession().setAttribute("user", user);
		response.sendRedirect("/kick/index.jsp");
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值