来兄弟连上课,每天都算着天数,到现在已经有62天了,实实在在的学了62天,我觉得来兄弟连的这段日子是我过的最充实的,而且必将充实到离开兄弟连
每天上午8:20到12:20,4个小时的课堂时间;下午2点到5:30自自习整理上午老师教授的内容;晚上7:00开始自习,最早晚上12点离开教室一直这样有规律的充实的生活,渴望着自己在此养成主动学习的习惯
在此必须感谢我们的两个主讲老师:佟刚老师和张晓飞老师;佟刚老师见多识广给我们讲得很全面,也能把握细节,让我们学的很high;晓飞老师则给我们讲得很细致,让我们基础学的更加牢实。主讲老师让我们在轻松愉悦的环境下听讲对经历过9年义务教育的我们来说真是有多么的就有多么的轻松愉悦(学校整体给人的感觉也是如此,当然你必须把学习搞好)。
还有我们的代理班主任,张晓光老师,虽然只代理了我们班的班主任不长的时间,但给我们的印象是他代表着绝对的权利,我们班的规则几乎都是他定的,这对一个六七十人的大集体是一个必须的链子。我们班主任徐彩辉老师更多的关注是我们班的生活和学习上的事情(张晓光老师不光只管我们班),倒像是我们的一个保姆...或者说是一个护驾者(哈哈)
还有一个人我们必须要提一下,谁呢?当然是我们的大boss李超校长,这个都不用说为什么要感谢李老大了(不知道为什么说明你不大适合做程序员)――真的像个大佬
以上是必须说明的,也是我从2012年10月19日到2013年1月1日这2个多月来对兄弟连的感受
不管学习条件有多好或多坏,学习好坏的决定性因素都在你,我们现在还可以对自己狠一点,所以更加努力吧
以下是我对监听器的一点理解,算是我的一个所学知识点的理解
<笔记>
监听器就是Servlet规范中定义的一组特殊的类,用于监听一些域对象的状态信息,当被监听的域对象的状态信息有了变化时,则会触发监听程序相应的动作,它是一个服务器端的组件
我们监听的域对象一般是application, session, request,它们都有以下几种状态信息:创建对象,增加属性,删除属性,修改属性,销毁对象。所以Servlet规范中定义了几个接口,并在接口中定义了相应的方法。
Servlet规范中还关心了一个特殊的情况,JavaBean对象在session域对象中的添加或移除,序列化或反序列化
</笔记>
(Copy)
Servlet 规范为每种事件监听器都定义了相应的接口,开发人员编写的事件监听器程序只需实现这些接口,web 服务器根据用户编写的事件监听器所实现的接口把它注册到相应的被监听对象上。一些 Servlet 事件监听器需要在 web 应用程序的 web.xml 文件中进行注册,一个 web.xml 文件中可以注册多个 Servlet 事件监听器,web 服务器按照它们在 web.xml 文件中的注册顺序来加载和注册这些 Servlet 事件监听器。
Serlvet 事件监听器的注册和调用过程都是由 web 容器自动完成的,当发生被监听的对象被创建,修改或销毁事件时,web容器将调用与之相关的 Servlet 事件监听器对象的相关方法,开发人员在在这些方法中编写的事件处理代码即被执行。由于一个 web 应用程序只会为每个事件监听器创建一个对象,有可能出现多个线程同时调用同一个事件监听器对象的情况,所以,在编写事件监听器类时,应考虑多线程安全的问题
相关API(按监听的事件类型 ):
① 监听域对象自身的创建和销毁的事件监听器:
① ServletContextListener 接口
contextInitialized (ServletContextEvent sce):当ServletContext 对象被创建时
contextDestroyed(ServletContextEvent sce):当 ServletContext 对象被销毁时
② HttpSessionListener接口
sessionCreated (HttpSessionEvent se): 当一个HttpSession对象被创建时
sessionDestroyed (HttpSessionEvent se): 当一个HttpSession对象被销毁时
③ ServletRequestListener 接口
requestInitialized(ServletRequestEvent sre):HttpServletRequest对象被创建时
requestDestroyed(ServletRequestEvent sre):HttpServletResponse对象被销毁时
② 监听域对象中的属性的增加和删除的事件监听器
ServletContextAttributeListener接口
public void attributeAdded(ServletContextAttributeEvent scae)
public void attributeReplaced(ServletContextAttributeEvent hsbe)
public void attributeRmoved(ServletContextAttributeEvent srae)
HttpSessionAttributeListener 接口
public void attributeAdded(HttpSessionBindingEvent scae)
public void attributeReplaced(HttpSessionBindingEvent hsbe)
public void attributeRmoved(HttpSessionBindingEvent srae)
ServletRequestAttributeListener接口
public void attributeAdded(ServletRequestAttributeEvent scae)
public void attributeReplaced(ServletRequestAttributeEvent hsbe)
public void attributeRmoved(Attributiveness srae)
③ 监听绑定到 HttpSession 域中的某个对象的状态的事件监听器接口
HttpSessionBindingListener接口,
JavaBean 对象可以感知自己被绑定到 Session 中和从 Session 中删除的事件
void valueBound(HttpSessionBindingEvent event) , 当前对象被添加到session中
void valueUnbound(HttpSessionBindingEvent event),当前对象从session中移除
HttpSessionActivationListener接口
实现了此接口的 JavaBean 对象可以感知自己被活化和钝化的事件
void sessionWillPassivate(HttpSessionBindingEvent event) ,当前对象被序列化前
void sessionDidActive(HttpSessionBindingEvent event),当前对象被反序列化前
(/Copy)
下面,我们来实现一个应用:实时显示当前在线用户列表
分析:
这个应用的主要实现的是在线用户的显示,当我们退出时,我们的用户名不会显示在在线用户的列表中,故需要监听的域有
application:
当部署这个应用的时候,新建一个list表,用来存储用户名;
实现的接口是:ServletContextListener 接口,
使用的方法是contextInitialized (ServletContextEvent sce),在此方法中得到application域对象,并新建一个list属性来存储用户名
application = sce.getServletContext();
application.setAttribute("onlineList", new ArrayList<String>());
Session:
session的建立到不需要什么特殊的处理;当一个会话增添一个属性或者删除一个属性时,我们需要监听,
实现的接口是:HttpSessionAttributeListener接口
使用的方法是:
当增加属性时,在attributeAdded(HttpSessionBindingEvent se)方法中获得新增属性的名和值,若此名和我们需要的属性名一致,则添加此属性的值到list中,否则无动作。
String key = se.getName();
String value = (String)se.getValue();
if("user".equals(key)) {
List<String> allOnlineList = (List<String>) application.getAttribute("onlineList");
allOnlineList.add(value);
}
当删除属性时,在attributeRemoved(HttpSessionBindingEvent se)方法中获得删除属性的名和值,若此名和我们需求的属性名一致,则从list中删除此属性名的值,否则无动作。
String key = se.getName();
String value = (String)se.getValue();
System.out.println(key+" "+value);
if("user".equals(key)) {
List<String> allOnlineList = (List<String>) application.getAttribute("onlineList");
allOnlineList.remove(value);
}
当一个session销毁或失效的时候,属于此session的属性已属无效,我们需要把对应的用户名从list列表中删除,故需要进行监听处理,
实现的接口是:HttpSessionListener接口
使用的方法是:sessionDestroyed(HttpSessionEvent se),在此方法中我们从list列表中移除这个session的user属性的username值
List<String> allOnlineList = (List<String>) application.getAttribute("onlineList");
allOnlineList.remove(se.getSession().getAttribute("username"));
具体实现:
1.index.jsp页面:仅仅注册一个用户账号即可登录
<body>
<form action="login.jsp">
用户名:<input type="text" name="username"/>
<input type="submit" value="登录"/>
</form>
</body>
填入用户名后,点击登录,转向login.jsp页面
Application域创建监听
2.login.jsp页面:
<body>
<%
session.setAttribute("user",request.getParameter(username))
response.sendRedirect("list.jsp")
%>
</body>
获取index页面填入的username并把它保存在session的user属性中
重定向到list.jsp
Session域增加属性监听
3.list.jsp页面:使用jstl标签进行遍历,故,需添加 这两个jar包
并在jsp页面中引入标签库文件:
<%@ taglib url="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<body>
<h3>Hello,${sessionScope.user}</h3>
<a href="loginoff.jsp">注销</a><br>
在线的用户:<br>
<c:forEach items="${onlineList}" var="item">
${item}<br>
</c:forEach>
</body>
当我们注册用户进入此页面时,我们的用户名会在在线的用户下面显示,当我们刷新此页面时,新添加的用户或者删除的用户会各安其位。
点击注销,转向loginoff.jsp页面
4.loginoff.jsp页面:删除当前的用户信息,或者使当前的session失效,转向index.jsp 页面
<body>
<%
session.removeAttribute("user");
// session.invalidate();//使session失效
response.sendRedirect("index.jsp");
%>
</body>
Session域删除属性监听,session域失效监听
5.界面这块我们做好了,下面的就是监听程序了
由分析可知,我们的监听程序需要实现的接口有三个:ServletContextListener ,
HttpSessionAttributeListener,HttpSessionListener
源程序(对session属性的替换也进行了相应的处理):
package jin;
import java.util.ArrayList;
import java.util.Date;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class OnlineList implements ServletContextListener, HttpSessionListener, HttpSessionAttributeListener {
private ServletContext servletContext;
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println("移除");
System.out.println(new Date().toLocaleString());
System.out.println("....................................");
String key = se.getName();
String value = (String) se.getValue();
if("user".equals(key)){
ArrayList<String> list = (ArrayList<String>) servletContext.getAttribute("onlineList");
list.remove(value);
}
}
public void attributeAdded(HttpSessionBindingEvent se) {
System.out.println("新增");
System.out.println(new Date().toLocaleString());
System.out.println("....................................");
String key = se.getName();
String value = (String) se.getValue();
if("user".equals(key)){
ArrayList<String> list = (ArrayList<String>) servletContext.getAttribute("onlineList");
list.add(value);
}
}
public void contextInitialized(ServletContextEvent sce) {
System.out.println("部署");
System.out.println(new Date().toLocaleString());
System.out.println("....................................");
servletContext=sce.getServletContext();
servletContext.setAttribute("onlineList",new ArrayList<String>());
}
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("替换");
System.out.println(new Date().toLocaleString());
System.out.println("....................................");
ArrayList<String> list = (ArrayList<String>) servletContext.getAttribute("onlineList");
String key = se.getName();
String value = (String) se.getValue();
if("user".equals(key)) {
list.remove(value);
list.add((String) se.getSession().getAttribute("user"));
}
}
public void sessionCreated(HttpSessionEvent se) {
System.out.println("会话建立");
System.out.println(new Date().toLocaleString());
System.out.println("....................................");
}
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("会话结束");
System.out.println(new Date().toLocaleString());
System.out.println("....................................");
ArrayList<String> list = (ArrayList<String>) servletContext.getAttribute("onlineList");
list.remove(se.getSession().getAttribute("user"));
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("部署撤销");
System.out.println(new Date().toLocaleString());
System.out.println("....................................");
}
}
问题:
我们用多个浏览器访问,留下我们的用户名,当这几个浏览器都关掉后,我们刷新list页面,已经关掉的浏览器用户名依然还在在线列表中显示。。。
原因:当关掉浏览器的时候,session依然存储在服务器中,session在服务器中是有有效时间限制的。
由于篇幅问题,这里就不谈如何解决了...
总结:监器是比较容易理解的,我们使用它来监听自己感兴趣的域对象的状态信息,并随着状态信息的不同进行不同的程序处理处理。
ApplicationSession Request域对象 |
监听器(实现所选接口,重写监听的方法) |
Servlet |
有动作(创建,销毁,改,添删.) |
监听到所关注的动作 |
一个简单的理解图
</笔记>
结束:
现在在看java基础,觉得很容易理解
学习web给人的感觉就是一个一个功能模块的学习(按需求学习),比较能提起兴趣。有些东西理解有些困难,但当我们的视界开阔的时候,相信就会像现在看java基础一般理解的更加透彻。
所以,继续努力吧