• 1.6(学习笔记)Session


    一、 Session简介

      Session是用于解决HTTP无状态问题,HTTP协议本身是没有状态的,

      就类似一个没有记性的商人,每次只交易当前的货物,交易完后就忘记了

      以前的交易历史。我们和商人交易时当然希望商人记住我们的一些信息,

      (例如购买的货物等),这样商人就可以根据我们的信息,提供一些定制

      的服务。

      而Session、Cookie就是解决商人的记性问题,使商人能够记住我们的信息。

      Cookie可参阅:

      现在商人想了一个办法,他每次交易后给我们一张小卡片,卡片上只有一个编号。

      然后商人这里有一个记账本,每次交易时我们把小卡片给商人,商人根据小卡片上面的

      编号修改自己的记账本。这个记账本就是Session,这个编号是Session ID,这个小卡片

      是Cookie。

      Session是存储在服务器的,Cookie是存储在客户端的。

     

      Session的创建

      Session在用户端访问时便不会被默认创建,而是通过request.getSession();创建第一个Session.

      //如果存在Session则返回关联的Session,如果不存在则创建Session。

      HttpSession request.getSession();

      

      Session的销毁

      Session销毁主要有两种情况,一是手动销毁通过调用session.invalidate()方法销毁。

      二是Session默认30分钟没有使用,则服务器自动销毁。

      默认销毁时间可以通过web.xml中设置,单位是分钟。

    <session-config>
          <!--设置Session默认有效期,单位分钟--> <session-timeout>15</session-timeout> </session-config>

      

      Session会话过程

      首先但不存在Session时,调用request.getSession()会创建一个Session。

      同时这个Session的ID会以Cookie写入到客户端。

      下一次客户端访问服务器时,reques会发送Cookie,服务器就会读取Cookie中

      对应的SessionID,然后服务器根据读取的SessionID寻找存储的Session。

      

      Session的URL重定向

      由上述得知,Session的ID使用Cookie存储在客户端,但是这种方法并不可靠。

      用户可能禁用Cookie,Cookie被禁用后我们就无法通过Cookie获取SessionID,

      这时就需要采用URL重定向将SessionID以参数的形式作为URL的一部分传递给服务器,

      以保障Session在Cookie禁用的情况下能正常使用。

      

     二、Session实例

      用户购买书籍,通过Session记录已购买书籍。

      程序流程:

      BuyIndexServlet:

      根据图书编号动态生成将购买带书籍ID作为参数传递的的购买链接。

      点击购买链接后,跳转到BuyServlet。

      BuyServlet:

      session = getSession();

      //获取Session中用户购书清单

      list = session.getAttribute("lisi");

      if(list == null){

        new list;

      }

      list.add("用户选中图书")

      session.setAttribute(list);

      请求跳转到showBuyBookServlet。

      showBuyBookServlet:

      //获取Session中书籍购买清单

      llist = request.getSession().getAttribute("list");

      遍历输出list内容,即已购买书籍。

      

      Cookie未禁用版本:

    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    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 IndexServlet extends HttpServlet{
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setCharacterEncoding("utf-8");
            PrintWriter out = resp.getWriter();
            //打印HTML头部代码
            HttpPageUtil.printHtmlPage(out,true);
            //生产将书籍ID作为参数的购买链接
            //链接:http://localhost:8080/TestServlet/TestServlet/BuyServlet?id=3
            for(Entry<String, Book> s : Lib.getAll().entrySet()) {
                Book book = s.getValue();
                out.println("<a href = "+ req.getContextPath() + "/TestServlet/BuyServlet?id="+ book.getId() +">"
                            + book.getName() +"</a>");
            }
            //打印HTML尾部代码
            HttpPageUtil.printHtmlPage(out,false);
        }
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
    //全部书籍
    class Lib{
        private static Map<String,Book> map = new HashMap<>();
        static {
            map.put("1", new Book("1","深入理解操作系统"));
            map.put("2", new Book("2","计算机网络"));
            map.put("3", new Book("3","数据结构与算法"));
            map.put("4", new Book("4","计算机组成原理"));
            map.put("5", new Book("5","编译原理"));
        }
        
        public static Map<String,Book> getAll(){
            return map;
        }
    }
    
    class Book{
        private String id;
        private String name;
        public String getId() {
            return id;
        }
        
        public Book() {};
        
        public Book(String id, String name) {
            setId(id);
            setName(name);
        }
        
        public void setId(String id) {
            this.id = id;
        }
        
        public String getName() {
            return name;
        }
        
        public void setName(String name) {
            this.name = name;
        }
    }

    BuyServlet:

    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    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 BuyServlet extends HttpServlet{
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            HttpSession session = req.getSession();
            String buyBookId = req.getParameter("id");
            //获取Session中的书籍购买清单
            List<Book> list = (List<Book>)session.getAttribute("list");
            if(list == null) {
                list = new ArrayList<>();
            }
            //将选中书籍添加到清单中
            list.add(Lib.getAll().get(buyBookId));
            session.setAttribute("list", list);
            //请求转发到显示界面。
            req.getRequestDispatcher("/TestServlet/showBuyBook").forward(req, resp);
        }
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req,resp);
        }
    }

    showBuyBookServlet:

    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.List;
    
    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 showBuyBook extends HttpServlet{
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setCharacterEncoding("utf-8");
            PrintWriter out = resp.getWriter();
            HttpSession session = req.getSession();
            //获取Session中的书籍购买清单
            List<Book> list = (List)session.getAttribute("list");
            if(list == null){
                out.println("<h1>你没有购买任何商品</h1>");
                return;
            }
            HttpPageUtil.printHtmlPage(out, true);
            //输出已购买书籍
            for(Book book : list) {
                out.println("<h2>" + book.getName() + " </h2>");
            }
            HttpPageUtil.printHtmlPage(out, false);
        }
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }

     

    Cookie被禁用版:(通过URL重写,将SessionID作为URL的参数传递)。

    但Cookie被禁用使用Session时,主要通过传递SessionID来实现Session的共享。

    而Session则将被作为URL的一部分,这需要使用URL重写方法。

    String javax.servlet.htttp.HttpServletResponse.encodeURL(java.lang.String url);

    将SessionID添加到URL,生成新的URL。

    (如果Cookie没有被禁用则此方法不生效,只有Cookie被禁用此方法才生效)

    BuyIndexServlet

    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    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 IndexServlet extends HttpServlet{
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setCharacterEncoding("utf-8");
            req.getSession();//创建Session
            PrintWriter out = resp.getWriter();
            //打印HTML头部代码
            HttpPageUtil.printHtmlPage(out,true);
            //生产将书籍ID作为参数的购买链接
            //链接:http://localhost:8080/TestServlet/TestServlet/BuyServlet?id=3
            for(Entry<String, Book> s : Lib.getAll().entrySet()) {
                Book book = s.getValue();
                String url = req.getContextPath() + "/TestServlet/BuyServlet?id="+ book.getId();
                //重写URL,将SessionID添加到URL中
                //重写前URL:http://localhost:8080/TestServlet/TestServlet/BuyServlet?id=1
                //重写后URL:
                //http://localhost:8080/TestServlet/TestServlet/BuyServlet;jsessionid=A6722323929D7B76FE66B6F39E188D87?id=1
                //其中jsessionid代表sessionID
                url = resp.encodeURL(url);
                out.println("<a href = " + url +"> " + book.getName() +"</a>");
            }
            //打印HTML尾部代码
            HttpPageUtil.printHtmlPage(out,false);
        }
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
    //全部书籍
    class Lib{
        private static Map<String,Book> map = new HashMap<>();
        static {
            map.put("1", new Book("1","深入理解操作系统"));
            map.put("2", new Book("2","计算机网络"));
            map.put("3", new Book("3","数据结构与算法"));
            map.put("4", new Book("4","计算机组成原理"));
            map.put("5", new Book("5","编译原理"));
        }
        
        public static Map<String,Book> getAll(){
            return map;
        }
    }
    
    class Book{
        private String id;
        private String name;
        public String getId() {
            return id;
        }
        
        public Book() {};
        
        public Book(String id, String name) {
            setId(id);
            setName(name);
        }
        
        public void setId(String id) {
            this.id = id;
        }
        
        public String getName() {
            return name;
        }
        
        public void setName(String name) {
            this.name = name;
        }
    }

    BuyServlet:

    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    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 BuyServlet extends HttpServlet{
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            HttpSession session = req.getSession();
            String buyBookId = req.getParameter("id");
            //获取Session中的书籍购买清单
            List<Book> list = (List<Book>)session.getAttribute("list");
            if(list == null) {
                list = new ArrayList<>();
            }
            //将选中书籍添加到清单中
            list.add(Lib.getAll().get(buyBookId));
            session.setAttribute("list", list);
            //重写URL,并重定向到重写后的URL。
            //重写后的URL:
            //http://localhost:8080/TestServlet/TestServlet/showBuyBook;jsessionid=A6722323929D7B76FE66B6F39E188D87
            String url = resp.encodeRedirectURL(req.getContextPath() + "/TestServlet/showBuyBook");
            resp.sendRedirect(url);
        }
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req,resp);
        }
    }

    showBuyBookSelvelt:与Coolie未禁用版相同。

     

     可以看到地址栏右边的一个图标有一个小红叉,代表禁用Cookie。但Cookie禁用后,无法从Cookie读取到SessionID。

    此时主要通过URL重写来传递SessionID,其他Servlet可以通过传递过来的SessionID获取Session。

    而且我们会发现,重写的URL都加上了jsessionid=....;这就是SessionID,服务器主要通过

    这个ID来寻找存储的Session。

    参考资料:

    https://www.cnblogs.com/xdp-gacl/p/3855702.html

    https://www.cnblogs.com/lonelydreamer/p/6169469.html

    https://blog.csdn.net/weixin_42139757/article/details/80467518

  • 相关阅读:
    Java Evaluate Reverse Polish Notation(逆波兰式)
    UVA 11427
    iOS8互动的新通知
    Codeforces 32E Hide-and-Seek 乞讨2关于镜面反射点 计算几何
    error: png.h not found.
    JAVA反射机制
    java24 手写服务器最终版本
    java23 XML
    java22
    java21 封装Response:
  • 原文地址:https://www.cnblogs.com/huang-changfan/p/10305086.html
Copyright © 2020-2023  润新知