Session浅谈

在web开发中,服务器可以为每个用户浏览器创建一个会话对象(Session对象),注意,一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以将用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其他程序时,其他程序可以从用户的session中取出该用户的数据,为用户服务

Session和Cookie的区别

Cookie是将用户的数据写给用户的浏览器,cookie用于在客户端保存用户信息

Session是将用户的数据写到用户独占的Session中,session用于在服务器端保存用户信息

PS:Servlet中的Session和JSP中的Session的关系

这两个session都是javax.servlet.http.HttpSession类的实例,本质上他们是一样的,servlet中需要通过request.getSession()来获取session对象,而JSP中可以直接使用,每个用户对应一个session对象。

Session对象由服务器创建,开发人员可以调用request的getSession方法得到session对象

session的生:request.getSession()    注意:request.getSession(false) 是只获取不创建session

request.getSession(); //服务器会首先检测有没有带cookie过来的session,如果有则获取session,如果发现浏览器禁用了cookie,再检测有没有带重写URL的session,有获取,上述两个都没有带过来,就会创建新的session 

session的死:如果session在30分钟不被使用(不管关不关浏览器) 会自动摧毁session 另外在web.xml文件中也可以配置session的失效时间

用配置的方式摧毁session:

<session-config>

    <session-timeout>10</session-timeout>  <!-- 10分钟内不使用自动销毁 -->

</session-config>

用代码的方式摧毁session:

session.invalidate();   //调用该方法来摧毁session

session的实现原理


session的具体实现基于cookie

request.getSession()首先用于判断服务器是否有创建session,如果没有,则创建一个session,每个session创建的时候都会有个ID值,服务器将该ID值以cookie的方式回写给浏览器,再次访问另一个程序时,cookie会带着该session的ID,所以,第二次在获取session的时候,不会创建session,而是会获取到该cookie所带的ID值对应的session。

但是该cookie没有设置有效期,所以关闭浏览器后,session也将失效。为了解决该问题,需要重写cookie,并设置该cookie的生命周期,值得一提的是,保存sessionID的cookie是一个固定的cookie,该cookie的名称为JSESSIONID,所以可以通过创建这个Cookie覆盖原来的cookie

                String cookieId = session.getId();  //获取session的ID值
Cookie cookie = new Cookie("JSESSIONID",cookieId); //重新创建该cookie,覆盖原来没有生命周期的cookie
cookie.setMaxAge(30*60); //设置cookie的生命周期为半个小时
cookie.setPath("/servlet"); 

response.addCookie(cookie); //服务器回写cookie给浏览器 覆盖之前系统的同名但无生命长度的cookie

上述代码的作用是,

当首次打开浏览器,访问一个名称为SessionBuy的servlet

public class SessionBuy extends HttpServlet {

               public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession(); //首次访问服务器,服务器创建session并将sessionID回写给cookie
session.setAttribute("product", "洗衣机"); //设置session的值

}

}

再次访问另一个名称为sessionPay的servlet

public class SessionPay extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession(false);  //给句cookie带过来的sessionID获取相应的session
out.print("您购买的额商品是: "+session.getAttribute("product")); //输出session的值

}

}

访问两个servlet的页面index.html

<html>
  <head>
    
    <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
  </head>
  
  <body>
  <a href='/servlet/servlet/SessionBuy'>购买</a>
  <a href='/servlet/servlet/SessionPay'>付款</a>
  </body>
</html>

上述代码存在的一个问题是,创建的携带sessionID的cookie是系统默认创建的cookie,该cookie的没有setMaxAge(),即该cookie没有生命长度,一旦关闭浏览器,打开一个新的浏览器,该cookie已经不存在,下次通过sessionPay的servlet去获取session个的值时,由于此时cookie已经失效,所以获取不到session的数据

1.访问index.html页面

2.点击购买链接,访问SessionBuy

3.返回index.html,点击付款链接,将会显示购买的商品为  洗衣机

4.关闭浏览器 重新打开一个新的浏览器,点击付款链接 发现显示购买商品为 null

即先点击购买,会创建session,并自动创建一个sessionID, 该sessionID赋值给一个叫JSESSIONID的cookie,并将该cookie回写给浏览器,当再点击付款时,服务器会根据该浏览器的名称为JSESSIONID的cookie带过来的sessionid,获得购买时创建的session,并打印该session所带的值。但是JSESSIONID这个cookie是系统自己生成的,它的MaxAge值为0,也就是说当关闭浏览器重新打开一个浏览器,该cookie就不再生效,这时候直接点击付款,会发现显示的值为null。

为了解决关闭浏览器,重新打开浏览器再次获取session的值的问题,需要重新并覆盖创建系统的默认cookie,该该cookie设置一个生命周期,这样就解决了上述问题。

1.访问index.html页面

2.点击购买链接,访问SessionBuy

3.返回index.html,点击付款链接,将会显示购买的商品为  洗衣机

4.关闭浏览器 重新打开一个新的浏览器,点击付款链接 发现显示购买的商品还是 洗衣机

5.说明此时的cookie还在生效 上述问题得以解决

将上述SessionBuy的servlet的代码增加红色部分:

public class SessionBuy extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession();
String cookieId = session.getId(); //获取cookie携带的sessionID
Cookie cookie = new Cookie("JSESSIONID",cookieId); //覆盖系统默认的cookie,该cookie的名称为JSESSIONID
cookie.setMaxAge(30*60); //设置该cookie的存活期为半个小时,关闭浏览器再次打开浏览器该cookie依然存在
cookie.setPath("/servlet");
response.addCookie(cookie);  //将服务器该cookie回写给浏览器

session.setAttribute("product", "洗衣机");

}

}

URL重写

session的实现机制是cookie,通过cookie携带sessionID来标识session,但是如果浏览器禁用了cookie,该怎么办?我们需要想办法将sessionID通过另一个介质带给浏览器,这时候就需要一个新的技术,URL重写,即将sessionID加在超链接的后面

在上述代码的基础上加一个新的servlet

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
PrintWriter out = response.getWriter();

request.getSession();  //创建session
String url1 = response.encodeURL("SessionBuy"); //URL重写 通过该方法给URL后面添加一个ID
String url2 = response.encodeURL("SessionPay");
 
out.print("<a href='"+url1+"'>购买</a> ");
out.print("<a href='"+url2+"'>结账</a>");

}

URL重写 无法解决  4.关闭浏览器 重新打开一个新的浏览器,点击付款链接 发现显示购买商品为 null 这个问题

学习笔记 多有不足!!!


猜你喜欢

转载自blog.csdn.net/kermit_father/article/details/80467905