1.7
思路:
a.servlet是单实例多线程运行的。因此当多客户端访问时可能会产生线程安全问题。特别是用servlet作购物车时更要注意。
b.servlet的监听机制。常见监听分类: 1.用于监听与对象自身创建和销毁的时间监听器 2.用于监听与对象中的属性的增加和删除的事件监听。 3.用于监听绑定到httpSession域中的某个对象的状态的时间监听器。(唯一不用在web.xml注册测的监听器)4.钝化和活化概念
c.整合案例:获取当前在线人数
Servlet线程安全问题
Servlet是单实例多线程运行的。
解决:
1.实现 SingleThreadModel 接口
该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法讲不会有两个线程被同时执行,当然也就不存在线程安全的问题。
定义如下:
Public class HelloWorldServlet extends HttpServlet implements SingleThreadModel { }
2.不使用全局变量,实例变量对所有线程是共有的,会产生并发问题。
3.尽量使用局部变量,因为局部变量对每个线程都是私有的。
4. 同步对共享数据的操作
使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
synchronized (this){ //同步代码块
PrintWriter out=response.getWriter();
out.println("<html><body>您好,欢迎您来到这个世界上<html><body>");
System.out.println("service");
}
}
Servlet监听器
HttpContextListener
HttpSessionListener //可作在线人数统计
HttpServletRequestListener
Servlet属性监听器
HttpContextAttributeListener
添加, //添加方法执行了两次.第一次是系统的值.第二次是自定义的值
删除, //获取的是删除的值
替换。 //在监听器中得到是替换前的值
HttpSessionAttributeListener
HttpServletRequestAttributeListener
Servlet绑定的事件监听
httpSessionBindingListener接口 不需要在web。Xml中注册
valueBound(HttpSessionBindingEvent event) //当实现该接口的JavaBean对象被放置到sesion作用于中是调用该方法
当改变绑定的值时的过程:先绑定新值先调用valueBound,然后接触与老值的绑定 调用valueUnbound
valueUnbound(HttpSessionBindingEvent event) //当实现该接口的JavaBean对象从sesion作用删除时
重新看11:06的错误
httpSessionActivationListener接口 活化和钝化概念 序列化概念?
要实现的接口: HttpSessionActivationListener,java.io.Serializable
sessionDidActivate(httpSessionEvent se)
void sessionDidActivate(HttpSessionEvent se) // * 活化(把session从硬盘上读取到服务器的内存中)
void sessionWillPassivate(HttpSessionEvent se) // * 钝化(把服务器内存中的session信息存储到硬盘上,已被下次服务器启动,重新读取)
java.io.Serializable //序列化
实例:统计当前在线人数列表
//获取远程登录用户的IP
String ip=request.getRemoteAddr();
处理session过期问题:
用HttpSessionListener
获取在线人数实现思路:
a.区分游客和登录用户,因此需要在登录游客的bean中嵌套登录bean
b.将在线的人添加到游客集合,首先加入到游客中,然后如果登录则将其转入登录用户集合中。实现:在用户访问的首页面设置session的监听绑定。用户的登录信息存放到Map中放入到ServletContext中作全局保留。
c.设置session对象创建和销毁监听。如果session过期或用户下线则将该用户的信息从map集合中删除。当然session的默认活动时间为30中,所以统计可定会用一定的误差。
此工程需要的页面
index.jsp 游客可以访问,登录用户可以访问
chatper.jsp 只有登录用户才能访问(游客不能访问)
在WEB-INF/jsp下的 login.jsp 游客可以访问登录用户可以访问
在WEB-INF/jsp下的 title.jsp 只有登录用户才能访问(游客不能访问)
onlinenum.jsp --后台管理的jsp页面(登录用户和游客无权访问) --管理员
程序执行时,直接访问该index.jsp页面,也就是在地址栏中不需要输入index.jsp
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
游客流程:
index.jsp 转到 WEB-INF/jsp/login.jsp
<jsp:forward page="/WEB-INF/jsp/login.jsp"></jsp:forward>
* 服务器启动的时候就执行MyServletContextListener中的
public void contextInitialized(ServletContextEvent sce) {
System.out.println("MyServletContextListener contextInitialized");
//获取上下文对象
ServletContext sc=sce.getServletContext();
//定义集合存放游客和登录用户Map<sessionid,sessionUser>
Map onlineNum=new HashMap();
//集合放置到作用域中(范围最大的)
sc.setAttribute("onlineNum", onlineNum);
}