资源描述
会话管理和使用
1、HTTP协议的无状态
HTTP是无状态协议。如果一个协议不能记忆它之前的连接,就不能把某客户端的请求与另一个客户端区分开来,我们就说这个协议是无状态的。
<1.1> 什么是会话
<1.2> 状态和会话管理
2、Servlet API 对会话的支持
在Servlet API中使用HttpSession接口来实现会话,客户端向服务器发请求,服务器就会创建一个与当前请求相关联的会话对象。并使用HttpSession对象封装HTTP会话的重要信息,比如唯一的会话ID以及其他一些特定的客户信息。其中,特定的客户信息可以包含任何java对象。
<2.1> HttpSession接口
HttpSession接口实现了会话机制,并用Session来跟踪客户的状态。
<2.2> 会话对象的创建
在HttpServletRequest接口中定义了两种方式来创建会话,分别是getSession()和getSession(Boolean create)的方法。这两个方法都能返回与当前请求相关联的HttpSession对象。
<2.3> 会话管理
在Web应用中,会话必须很好地被管理,HttpSession接口中提供了管理会话的方法。P45
示例3-1:
package com3_1;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpSession;
public class GetSessionInfoServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("GBK");
response.setContentType("text/html;charset=GBK");
PrintWriter out = response.getWriter();
//获取与当前请求相关的会话
HttpSession session = request.getSession();
Date creationTime = new Date(session.getCreationTime());
Date lastAccessed = new Date(session.getLastAccessedTime());
Date now = new Date();
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
out.println("<HTML>");
out.println(" <HEAD><TITLE>显示会话的信息</TITLE></HEAD>");
out.println(" <BODY>");
out.print("<h2>会话创建和最后处理时间</h2>");
out.print("现在时间是:" + fmt.format(now) + "<br><br>");
out.println("会话创建时间是:" + fmt.format(creationTime) + "<br><br>");
out.println("会话ID是:" + session.getId() + "<br><br>");
out.println("会话最大活动期是:" + session.getMaxInactiveInterval() + "秒<br><br>");
out.println("最后处理时间是:" + fmt.format(lastAccessed));
out.println("<h2>HttpRequest的信息</h2>");
out.println("来自请求会话ID:" + request.getRequestedSessionId() + "<br>");
out.println("会话来自Cookie吗?:" + request.isRequestedSessionIdFromCookie() + "<br>");
out.println("会话是来自URL吗?:" + request.isRequestedSessionIdFromURL() +"<br>");
out.println("会话是有效的吗?:" + request.isRequestedSessionIdValid() + "<br>");
//销毁会话
session.invalidate();
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
}
3、会话跟踪
会话跟踪允许服务器确定访问站点的用户、用户访问站点的次数和用户停留站点的时间段。在客户端和服务器之间的会话ID和状态信息交换,Web服务器常有4种方法:
● 使用Servlet API中的Session机制
● 使用Cookic
● 分别是将会话ID存放在URL路劲中、执行URL重写
● 隐藏表单域
<1> 使用Session的会话跟踪
示例3-2:
package com3_2;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ColorServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("GBK");
response.setContentType("text/html;charset=GBK");
String name = "";
String color = "";
String sfont = "";
Integer hitCount = new Integer(0);
HttpSession session = request.getSession(true);
PrintWriter out = response.getWriter();
out.print("<html>");
out.print("<head><title>会话跟踪</title></head>");
if (session.isNew()) {
//第一次请求页面,创建Session对象
hitCount = new Integer(1);
out.print("<body>");
out.print("<form action=ColorServlet method=POST>");
out.print("<h3>请选择你喜欢的背景颜色和字体</h3>");
out.print("<input type = radio name= bcolor value = white checked>白色");
out.print("<input type = radio name = bcolor value = red >红色");
out.print("<input type = radio name = bcolor value = green >绿色");
out.print("<input type = radio name = bcolor value = blue >蓝色<br>");
out.print("<input type = radio name = sfont value = 隶属 checked>隶属");
out.print("<input type = radio name = sfont value = 宋体 >宋体");
out.print("<input type = radio name = sfont value = 方正舒体 >方正舒体<br>");
out.print("请输入你的名字<br>");
out.print("<input type = text name = name value = ''><br>");
out.print("<input type = submit name = submit value = 提交><br>");
out.print("</form>");
}else{
//第二请求,不再创建Session对象
//从request对象里拿值
color = request.getParameter("bcolor");
name = request.getParameter("name");
sfont = request.getParameter("sfont");
//其他的更多次的请求,此时,request对象里不再有值了
if (color != null&&name != null&&sfont != null) {
hitCount = new Integer(1);
session.setAttribute("color", color);
session.setAttribute("hitCount", hitCount);
session.setAttribute("name", name);
session.setAttribute("sfont", sfont);
}else{
//从不同的Session对象中取值
color = (String)session.getAttribute("color");
hitCount = (Integer)session.getAttribute("hitCount");
name = (String)session.getAttribute("name");
sfont = (String)session.getAttribute("sfont");
}
session.setAttribute("hitCount", new Integer(hitCount.intValue()+1));
out.print("<body bgcolor="+color+">");
out.print("<h2><font face = "+sfont+">你好!"+name+"</font></h2>");
out.print("<p><font face = "+sfont+">你请求这个页面"+hitCount+"次</font></p>");
out.print("<p><a href = ColorServlet>请求页面</a></p>");
}
out.print("</body>");
out.print("</html>");
out.flush();
out.close();
}
}
<2> 使用Cookie
Servlet API中提供了Cookie类来实现Cookie,并定义了添加Cookie和获取Cookie的方法,同时,也定义了管理Cookie的方法。
示例3-3代码:
package com3_3;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class CookieWriteAndReadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("GBK");
response.setContentType("text/html;charset=GBK");
//创建会话对象
HttpSession session = request.getSession();
//构造两个Cookie对象
Cookie customerID = new Cookie("customerID","123456");
Cookie color = new Cookie("color","blue");
customerID.setMaxAge(300);
color.setMaxAge(300);
//把Cookie添加到相应头
response.addCookie(customerID);
response.addCookie(color);
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>读取客户端的Cookie</title></head>");
out.println("<body>");
out.println("客户端本机上的Cookie<table border = '1'>");
out.println("<tr><td>cookie名字</td><td>cookie的值</td></tr>");
//获取客户端放在HTTP请求里面的所有Cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
//以表格的形式输出Cookie的名字和值
for (int i = 0; i < cookies.length; i++) {
out.println("<tr><td>"+ cookies[i].getName()+"</td>");
out.println("<td>"+ cookies[i].getValue() +"</td></tr>");
}
}
out.println("</table>下面是HTTP请求的信息");
out.println("<table border = '1'><tr><td>头名字</td><td>头的值</td></tr>");
//获取所有的请求头的信息
Enumeration en = request.getHeaderNames(); //接口
while (en.hasMoreElements()) {
//以表格的形式输出请求信息和名字和值
String name = (String) en.nextElement();
out.println("<tr><td>" + name + "</td><td>"+request.getHeader(name)+"</td></tr>");
}
out.println("<table>");
out.println("</body>");
out.println("<html>");
out.flush();
out.close();
}
}
<3>URL重写
在JavaWeb中,使用会话和Cookie来跟踪客户。Cookie是存放在客户端的机器上面,如果客户端的浏览器出于安全方面的考虑,在浏览器的隐私设置中阻止了所有的Cookie。这样,服务器就没有办法把一些信息写入到客户端,使用Cookie就没有用了。这个时候,我们还是需要跟踪客户。
Java Servlet API中为我们提供了会话跟踪的另一中机制,通常的做法是重写客户请求的URL,把Session ID添加到URL信息中。
URL重写其实就是在URL后面加上一个jsessionid参数,jsessionid的参数值是唯一的,所以可以跟踪某一会话。HttpServletResponse接口中提供了2中URL重写的方法,如下:方法 说明
String encodeURL(String url) 重写给定的url,包含Session ID
String encodeRedirectURL(String url) 使用sendRedirect方法时,重写给定的url,包含Session ID
示例3-4代码:
package com3_4;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class UrlRewriteServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("GBK");
response.setContentType("text/html;charset=GBK");
PrintWriter out = response.getWriter();
//创建会话对象
HttpSession session = request.getSession();
//获取路劲
String contextPath = request.getContextPath();
//使用URL重写方法
String newURL = response.encodeURL(contextPath + "/default.html");
out.println("<HTML>");
out.println(" <HEAD><TITLE>演示客户端禁用浏览器的Cookie</TITLE></HEAD>");
out.println(" <BODY>");
//根据新的URL地址来判断客户端是否禁用Cookie
if (newURL.endsWith(session.getId())) {
out.print("客户端禁用了Cookie,URL将重写<br>");
out.print("客户端请求的default.html页面新的URL是:<br>"+newURL+"");
}
else{
out.print("客户端使用了Cookie,URL将不变<br>");
out.print("客户端请求的default.html页面的URL是:<br>"+newURL+"");
}
out.print("<a href = "+newURL+">去到default.html</a>");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
}
【
<html>
<head>
<title>演示URL重写</title>
</head>
<body><h1>
使用了URL重写</h1>
</body>
</html>
】
<4>隐藏表单域
隐藏HTML表单域通常是用来存储状态信息。隐藏的变量操作就像HTML输入域(文本输入域、复选框和单选按钮)一样,提交页面给服务器时,客户端就会把该隐藏域的名/值对传给服务器。不同在于,客户端的页面是不能看到或是修改隐藏的HTML变量的值,但是在HTML的源代码中是可以看变量的值。
代码片段显示html变淡中隐藏表单域的用法:
<form action=”registerServlet” method = “post”>
邮件地址:<input type=”text” name = “email”><br>
年龄: <input type = “text” name “age”><br>
<!—使用隐藏表单域来传递两个数据-->
<input type = “hidden” name = “uname” value = “张三丰”>
<input type = “hidden” name = “pwd” value = “998”>
<input type = “submit” value = “提交到服务器”>
</form>
欢迎加群一起学习共享学习资料:
QQ群:219774917 本人新建群!
展开阅读全文