zoukankan      html  css  js  c++  java
  • JavaWeb-Session

    来源
    一、Session简单介绍

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

        Cookie是把用户的数据写给用户的浏览器。
        Session技术把用户的数据写到用户独占的session中。
        Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。

    三、session实现原理
    3.1、服务器是如何实现一个session为一个用户浏览器服务的?

       服务器创建session出来后,会把session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session id过来了,就会使用内存中与之对应的session为之服务。可以用如下的代码证明:
    复制代码

     1 package xdp.gacl.session;
     2
     3 import java.io.IOException;
     4 import javax.servlet.ServletException;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import javax.servlet.http.HttpSession;
     9
    10 public class SessionDemo1 extends HttpServlet {
    11
    12     public void doGet(HttpServletRequest request, HttpServletResponse response)
    13             throws ServletException, IOException {
    14
    15         response.setCharacterEncoding("UTF=8");
    16         response.setContentType("text/html;charset=UTF-8");
    17         //使用request对象的getSession()获取session,如果session不存在则创建一个
    18         HttpSession session = request.getSession();
    19         //将数据存储到session中
    20         session.setAttribute("data", "孤傲苍狼");
    21         //获取session的Id
    22         String sessionId = session.getId();
    23         //判断session是不是新创建的
    24         if (session.isNew()) {
    25             response.getWriter().print("session创建成功,session的id是:"+sessionId);
    26         }else {
    27             response.getWriter().print("服务器已经存在该session了,session的id是:"+sessionId);
    28         }
    29     }
    30
    31     public void doPost(HttpServletRequest request, HttpServletResponse response)
    32             throws ServletException, IOException {
    33         doGet(request, response);
    34     }
    35 }

    复制代码

      第一次访问时,服务器会创建一个新的sesion,并且把session的Id以cookie的形式发送给客户端浏览器,如下图所示:

      

      点击刷新按钮,再次请求服务器,此时就可以看到浏览器再请求服务器时,会把存储到cookie中的session的Id一起传递到服务器端了,如下图所示:

      

      我猜想request.getSession()方法内部新创建了Session之后一定是做了如下的处理
    复制代码

    1 //获取session的Id
    2 String sessionId = session.getId();
    3 //将session的Id存储到名字为JSESSIONID的cookie中
    4 Cookie cookie = new Cookie("JSESSIONID", sessionId);
    5 //设置cookie的有效路径
    6 cookie.setPath(request.getContextPath());
    7 response.addCookie(cookie);

    复制代码
    四、浏览器禁用Cookie后的session处理
    4.1、IE8禁用cookie

      工具->internet选项->隐私->设置->将滑轴拉到最顶上(阻止所有cookies)

      
    4.2、解决方案:URL重写

      response.encodeRedirectURL(java.lang.String url) 用于对sendRedirect方法后的url地址进行重写。
      response.encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写
    4.3、范例:禁用Cookie后servlet共享Session中的数据

    IndexServlet
    复制代码

     1 package xdp.gacl.session;
     2
     3 import java.io.IOException;
     4 import java.io.PrintWriter;
     5 import java.util.LinkedHashMap;
     6 import java.util.Map;
     7 import java.util.Set;
     8 import javax.servlet.ServletException;
     9 import javax.servlet.http.HttpServlet;
    10 import javax.servlet.http.HttpServletRequest;
    11 import javax.servlet.http.HttpServletResponse;
    12
    13 //首页:列出所有书
    14 public class IndexServlet extends HttpServlet {
    15
    16     public void doGet(HttpServletRequest request, HttpServletResponse response)
    17             throws ServletException, IOException {
    18
    19         response.setContentType("text/html;charset=UTF-8");
    20         PrintWriter out = response.getWriter();
    21         //创建Session
    22         request.getSession();
    23         out.write("本网站有如下书:
    ");
    24         Set> set = DB.getAll().entrySet();
    25         for(Map.Entry me : set){
    26             Book book = me.getValue();
    27             String url =request.getContextPath()+ "/servlet/BuyServlet?id=" + book.getId();
    28             //response. encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写
    29             url = response.encodeURL(url);//将超链接的url地址进行重写
    30             out.println(book.getName()  + "   购买
    ");
    31         }
    32     }
    33
    34     public void doPost(HttpServletRequest request, HttpServletResponse response)
    35             throws ServletException, IOException {
    36         doGet(request, response);
    37     }
    38 }
    39
    40
    41
    45 class DB{
    46     private static Map map = new LinkedHashMap();
    47     static{
    48         map.put("1", new Book("1","javaweb开发"));
    49         map.put("2", new Book("2","spring开发"));
    50         map.put("3", new Book("3","hibernate开发"));
    51         map.put("4", new Book("4","struts开发"));
    52         map.put("5", new Book("5","ajax开发"));
    53     }
    54     
    55     public static Map getAll(){
    56         return map;
    57     }
    58 }
    59
    60 class Book{
    61     
    62     private String id;
    63     private String name;
    64
    65     public Book() {
    66         super();
    67     }
    68     public Book(String id, String name) {
    69         super();
    70         this.id = id;
    71         this.name = name;
    72     }
    73     public String getId() {
    74         return id;
    75     }
    76     public void setId(String id) {
    77         this.id = id;
    78     }
    79     public String getName() {
    80         return name;
    81     }
    82     public void setName(String name) {
    83         this.name = name;
    84     }
    85 }

    复制代码

    BuyServlet
    复制代码

     1 package xdp.gacl.session;
     2
     3 import java.io.IOException;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 import javax.servlet.ServletException;
     7 import javax.servlet.http.HttpServlet;
     8 import javax.servlet.http.HttpServletRequest;
     9 import javax.servlet.http.HttpServletResponse;
    10 import javax.servlet.http.HttpSession;
    11
    12 public class BuyServlet extends HttpServlet {
    13
    14     public void doGet(HttpServletRequest request, HttpServletResponse response)
    15             throws ServletException, IOException {
    16         String id = request.getParameter("id");
    17         Book book = DB.getAll().get(id);  //得到用户想买的书
    18         HttpSession session = request.getSession();
    19         List list = (List) session.getAttribute("list");  //得到用户用于保存所有书的容器
    20         if(list==null){
    21             list = new ArrayList();
    22             session.setAttribute("list", list);
    23         }
    24         list.add(book);
    25         //response. encodeRedirectURL(java.lang.String url)用于对sendRedirect方法后的url地址进行重写
    26         String url = response.encodeRedirectURL(request.getContextPath()+"/servlet/ListCartServlet");
    27         System.out.println(url);
    28         response.sendRedirect(url);
    29     }
    30
    31     public void doPost(HttpServletRequest request, HttpServletResponse response)
    32             throws ServletException, IOException {
    33         doGet(request, response);
    34     }
    35
    36 }

    复制代码

    ListCartServlet
    复制代码

     1 package xdp.gacl.session;
     2
     3 import java.io.IOException;
     4 import java.io.PrintWriter;
     5 import java.util.List;
     6 import javax.servlet.ServletException;
     7 import javax.servlet.http.HttpServlet;
     8 import javax.servlet.http.HttpServletRequest;
     9 import javax.servlet.http.HttpServletResponse;
    10 import javax.servlet.http.HttpSession;
    11
    12 public class ListCartServlet extends HttpServlet {
    13
    14     public void doGet(HttpServletRequest request, HttpServletResponse response)
    15             throws ServletException, IOException {
    16         response.setContentType("text/html;charset=UTF-8");
    17         PrintWriter out = response.getWriter();
    18         HttpSession session = request.getSession();
    19         List list = (List) session.getAttribute("list");
    20         if(list==null || list.size()==0){
    21             out.write("对不起,您还没有购买任何商品!!");
    22             return;
    23         }
    24         
    25         //显示用户买过的商品
    26         out.write("您买过如下商品:
    ");
    27         for(Book book : list){
    28             out.write(book.getName() + "
    ");
    29         }
    30     }
    31
    32     public void doPost(HttpServletRequest request, HttpServletResponse response)
    33             throws ServletException, IOException {
    34         doGet(request, response);
    35     }
    36 }

    复制代码

      在禁用了cookie的IE8下的运行效果如下:

      演示效果
    演示效果
      通过查看IndexServlet生成的html代码可以看到,每一个超链接后面都带上了session的Id,如下所示
    复制代码

    1 本网站有如下书:
    javaweb开发   购买

    2 spring开发   购买

    3 hibernate开发   购买

    4 struts开发   购买

    5 ajax开发   购买


    复制代码

      所以,当浏览器禁用了cookie后,就可以用URL重写这种解决方案解决Session数据共享问题。而且response. encodeRedirectURL(java.lang.String url) 和response. encodeURL(java.lang.String url)是两个非常智能的方法,当检测到浏览器没有禁用cookie时,那么就不进行URL重写了。我们在没有禁用cookie的火狐浏览器下访问,效果如下:


      从演示动画中可以看到,浏览器第一次访问时,服务器创建Session,然后将Session的Id以Cookie的形式发送回给浏览器,response. encodeURL(java.lang.String url)方法也将URL进行了重写,当点击刷新按钮第二次访问,由于火狐浏览器没有禁用cookie,所以第二次访问时带上了cookie,此时服务器就可以知道当前的客户端浏览器并没有禁用cookie,那么就通知response. encodeURL(java.lang.String url)方法不用将URL进行重写了。
    五、session对象的创建和销毁时机
    5.1、session对象的创建时机

      在程序中第一次调用request.getSession()方法时就会创建一个新的Session,可以用isNew()方法来判断Session是不是新创建的

    范例:创建session
    复制代码

     1 //使用request对象的getSession()获取session,如果session不存在则创建一个
     2 HttpSession session = request.getSession();
     3 //获取session的Id
     4 String sessionId = session.getId();
     5 //判断session是不是新创建的
     6 if (session.isNew()) {
         response.getWriter().print("session创建成功,session的id是:"+sessionId);
     8 }else {
         response.getWriter().print("服务器已经存在session,session的id是:"+sessionId);
    10 }

    复制代码
    5.2、session对象的销毁时机

      session对象默认30分钟没有使用,则服务器会自动销毁session,在web.xml文件中可以手工配置session的失效时间,例如:
    复制代码

     1
     2
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      
       
      
    10     index.jsp
    11  
    12
    13  
    14    
    15         15
    16    
    17
    18

    复制代码

      当需要在程序中手动设置Session失效时,可以手工调用session.invalidate方法,摧毁session。

    1 HttpSession session = request.getSession();
    2 //手工调用session.invalidate方法,摧毁session
    3 session.invalidate();

  • 相关阅读:
    UVa 116 单向TSP(多段图最短路)
    POJ 1328 Radar Installation(贪心)
    POJ 1260 Pearls
    POJ 1836 Alignment
    POJ 3267 The Cow Lexicon
    UVa 1620 懒惰的苏珊(逆序数)
    POJ 1018 Communication System(DP)
    UVa 1347 旅行
    UVa 437 巴比伦塔
    UVa 1025 城市里的间谍
  • 原文地址:https://www.cnblogs.com/luckForever/p/7254462.html
Copyright © 2011-2022 走看看