保存在客户端的Cookie可以设置有效期,在有效期内浏览器携带响应路径下的Cookie访问服务器,服务器就可以获取用户之前的访问信息了。Session本质上是基于Cookie的,由于当服务器为浏览器创建Session之后会为每一个Session设置一个唯一的ID,用于区分不同访问者。这个SessionID就通过Cookie的形式发送给浏览器,之后每次浏览器访问服务器指定路径的资源的时候就会带着这个Cookie,服务器根据Cookie总的ID找到先前创建的Session,然后从Session中获取数据。
解决办法是自己生成一个Cookie将Session的ID写入,然后将写入了SessionID的且设置了有效期的Cookie写回给浏览器
创建:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 浏览器访问的时候使用getSession()为其创建Session
HttpSession session = request.getSession();
String sessionID = session.getId();
// Session的ID名称为JSESSIONID,可以通过HTTPWatch查看
Cookie cookie = new Cookie("JSESSIONID", sessionID);
cookie.setPath("/curpath"); // 设置cookie的路径
cookie.setMaxAge(30 * 60); // 设置的有效时间长度是session的存在时间 半个小时
response.addCookie(cookie);
session.setAttribute("mydata", "hello world");
}
获取:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(false); // 只获取不创建
String data = null;
if(session != null) // 判断是否获取了Session
data = (String) session.getAttribute("mydata");
<span style="white-space:pre"> </span>// Servlet中解决乱码
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter pwriter = response.getWriter();
pwriter.write("获取的数据是: " + data);
}
另外一种无法使用已经存在的Session的情形是用户浏览器将Cookie禁止了,那么Session的ID自然是无法发送给浏览器,进而也就没办法继续使用Session了。
解决这种问题可以采用URL重写的方式,每次点击链接的时候浏览器都会讲Session的ID发送给服务器,服务器就取用相应的Session并获取信息。但是在重写URL之前一定要先获取Session。
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter pwriter = response.getWriter();
<span style="white-space:pre"> </span>// 在进行URL重写的时候必须先创建Session
request.getSession();
// 然后重写URL,将Session的ID以URL的形式传递给服务器
// 以解决用户浏览器禁止Cookie导致的Session无法获取的问题
String url1 = response.encodeURL("/curpath/servlet/SessionDemo01");
String url2 = response.encodeURL("/curpath/servlet/SessionDemo02");
pwriter.write("<a href = '" + url1 + "'>发送</a><br/>");
pwriter.write("<a href = '" + url2 + "'>接收</a><br/>");
}
当然两种方法是可以一起使用的,getSession()方法会依次对从Cookie和URL中获取SessionID,而且如果Cookie没有被禁用,那么就不会再将SessionID追加到URL上。
两篇深入讲解Session原理的博文:
http://ywj-316.iteye.com/blog/722941
http://www.cnblogs.com/wangtao_20/archive/2011/02/16/1955659.html