-- 作者:admin
-- 发布时间:2010/10/14 17:21:45
-- [推荐]第五部分课堂讲稿——状态管理
1、用户跟踪 简单的方法是利用servlet的属性变量,如: <%@page c%> <html> <head> </head> <body> <%!int i=0; %> <% i=i+1; %> 你登录次数为:<%=i%> </body> </html>
但是该方法不能根据每个用户来区分
利用会话Session可以跟踪用户行为,可以实现创建、删除和销毁,保存会话等操作
另外,除了会话以外还有三种用户跟踪技术:Cookies,URL重写,隐藏式表单域 1)Cookies 可以实现用户跟踪,但是缺点在于容量一般不超过4KB,任何域不超过20个Cookie,而且敏感信息不应该使用此技术,另外,有些客户端阻止Cookie。同时,不做时间设置的Cookie只能在一次会话中使用 2)URL重写 在URL后附加标示会话的数据,并且服务器保存此数据,较少使用 3)隐含表单域 即Hidden控件,缺点在于用户可以查看源代码看到数据
2、几种方法的使用(登录次数统计) 隐含表单域 <%@page c%> <html> <head> </head> <body> <form method="get" action="index.jsp"> <% String countStr = request.getParameter("count"); int count = 1; if (countStr == null) { out.print("<input type=\'Hidden\' name=\'count\' value=\'1\'>"); } else { count = Integer.parseInt(countStr); count++; out.print("<input type=\'Hidden\' name=\'count\' value=\'" + count + "\'>"); } out.print("你登录" + count + "次"); %> <input type="submit" value=\'确认\'></form> </body> </html>
URL重写 <%@page c%> <html> <head> </head> <body> <% String countStr = request.getParameter("count"); int count = 1; if (countStr != null) { count = Integer.parseInt(countStr); count++; } out.print("你登录" + count + "次<br>"); out.print("<a href=\'index.jsp?count=" + count + "\'>确认</a>"); %> </body> </html>
Cookies使用 <%@page c%> <html> <head> </head> <body> <% int count = 1; Cookie[] cookieList = request.getCookies(); if (cookieList != null) { for (int i = 0; i < cookieList.length; i++) { Cookie myCookie = cookieList[i]; if (myCookie.getName().equals("count")) { count = Integer.parseInt(myCookie.getValue()) + 1; Cookie myCookieCounter = new Cookie("count", String .valueOf(count)); response.addCookie(myCookieCounter); } } } if (count == 1) { Cookie myCookieCounter = new Cookie("count", "1"); response.addCookie(myCookieCounter); } out.print("你登录" + count + "次<br>"); %> </body> </html>
Session使用 <%@page c%> <html> <head> </head> <body> <% String countStr = (String) session.getAttribute("count"); int count = 1; if (countStr != null) { count = Integer.parseInt(countStr); count++; } session.setAttribute("count", String.valueOf(count)); out.print("你登录" + count + "次<br>"); %> </body> </html>
3、Cookies 可以使用持久化的Cookie,如: <%@page c%> <html> <head> </head> <body> <% int count = 1; Cookie[] cookieList = request.getCookies(); if (cookieList != null) { for (int i = 0; i < cookieList.length; i++) { Cookie myCookie = cookieList[i]; if (myCookie.getName().equals("count")) { count = Integer.parseInt(myCookie.getValue()) + 1; Cookie myCookieCounter = new Cookie("count", String .valueOf(count)); myCookieCounter.setMaxAge(24 * 60 * 60); response.addCookie(myCookieCounter); } } } if (count == 1) { Cookie myCookieCounter = new Cookie("count", "1"); myCookieCounter.setMaxAge(24 * 60 * 60); response.addCookie(myCookieCounter); } out.print("你登录" + count + "次<br>"); %> </body> </html>
4、会话 JSP网页前加入的<%@page language="java" import="java.util.*" session="true"%> 默认session为"true",表明网页中隐含javax.servlet.http.HttpSession对象,可以使用,如不存在则创建,所以此句可以省略 利用session.setAttribute存放信息,每个对象值都用一个唯一的Key值来标示,所以整数需用 new Integer(1)来生成 利用session.getAttribute得到信息 利用session.getAttributeName得到对象的名称 利用session.removeAttribute删除对象 利用session.getId得到session标示 利用session.invalidate杀死会话 利用session.isNew判断是否是新会话 利用session.setMaxInactiveInterval设置超时过期间隔,以秒为单位(-1表示永不过期)
会话方法的使用: <%@page c%> <html> <head> </head> <body> <% if (session.isNew()) { out.println("New One!"); } %> <br> <%=session.getId()%> <br> <%=new java.util.Date(session.getCreationTime())%> <br> <%=new java.util.Date(session.getLastAccessedTime())%> <br> </body> </html>
上述Session属性的设置也可以在web应用程序的web.xml文件中定义,如设置过期时间:进行设置,如: <web-app> <session-config> <session-timeout>10</session-timeout> </session-config> </web-app>
关于session如何实现用户跟踪的原因,主要在于JSP的session容器能够在客户端产生对应session的cookie来维持客户状态,如果客户端不支持cookie,则session容器可以重写URL以实现用户跟踪。
这种自己重写URL的手工编写方法是在所有的超链前添加response.encodeURL方法重写URL值,如: <form name="loginForm" method="post" action="<%=response.encodeURL("index.jsp")%>"> 或者 <a href="<%=response.encodeURL("index.jsp")%>">重新访问</a> 一般此时会在网页源代码中发现: <form name="loginForm" method="post" action="index.jsp;jsessionid=72F23F843D42F6D9E6FBADCE8FFDA8DC">
<%@page c%> <html> <head> </head> <body> <form method="post" action="<%=response.encodeURL("index.jsp")%>"> <input type="submit" value="确认"> </form> </body> </html>
注意:请求两次就不再显示,原因在于浏览器的后续请求已经内置隐含的重写URL信息
事实上,自己完全可以在请求的URL后手工添加其他会话值来模拟其他会话,如: http://localhost:8088/myweb/index.jsp;jsessionid=42C232CC13903A2CF05C3CCF09478DE1
查看Session的Cookie信息: <%@page c%> <%@page import="java.util.*"%> <html> <head> </head> <body> <% Enumeration enumHeader = request.getHeaderNames(); while (enumHeader.hasMoreElements()) { String name = (String) enumHeader.nextElement(); String values = request.getHeader(name); if (values != null) out.println(values + "<p>"); } out.print(session.getId()); %> </body> </html>
Tomcat5的源代码如何支持jsessionid。 org.apache.coyote.tomcat5.CoyoteResponse类的toEncoded()方法支持URL重写。 String toEncoded(String url, String sessionId) { … StringBuffer sb = new StringBuffer(path); if( sb.length() > 0 ) { // jsessionid can\'t be first. sb.append(";jsessitext/html;charset=GBK"%> <html> <head> </head> <body> <% String countStr = (String) application.getAttribute("count"); int count = 1; if (countStr != null) { count = Integer.parseInt(countStr); count++; } application.setAttribute("count", String.valueOf(count)); out.print("你登录" + count + "次<br>"); %> </body> </html>
[此贴子已经被作者于2011-11-15 08:07:19编辑过]
|