Cookie与Session

# 1.cookie

1.会话概述

image-20220410212922813

产生问题:image-20220410213440303

解决:

image-20220410214616362

image-20220410214137500

image-20220410214549773

2.CookieAPI介绍

image-20220410215638826

image-20220410215504381

3.Cookie属性

1.获取客户端Cookied最后一次访问的时间,响应给客户端时更新最后一次访问时间

package com.xu.cookieAndsession;

import javafx.scene.chart.PieChart;

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 java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.IOException;
import java.util.Calendar;

/**
 * @auther xu
 * @date 2022/4/11 - 3:38
 */
public class CookieDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //创建一个输出流对象
        PrintWriter out= null;

        try {
            //指定服务器端解码方式
            resp.setCharacterEncoding("UTF-8");
            out = resp.getWriter();
            //获取客户端Cookied最后一次访问的时间
            //1.获取该cookie数组(一个服务器在客户端缓存中最多保存20个Cookie)
            Cookie[] cookies = req.getCookies();

            //2.遍历cookie数组
            for (int i = 0; cookies != null && i < cookies.length; i++) {//客户端第一次访问服务器时request对象中不会携带Cookie
                if ("lastAccessTime".equals((cookies[i].getName()))) {
                    String value = cookies[i].getValue();
                    //2.将得到的时间格式化
                    long l = Long.parseLong(value);
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String format = simpleDateFormat.format(l);

                    //3.响应给客户端
                    out.write(format);
                }
            }
            //4.创建cookie对象
            Cookie lastAccessTime = new Cookie("lastAccessTime", System.currentTimeMillis() + "");
            //5.将Cookie响应给客户端,更新客户端缓存
            resp.addCookie(lastAccessTime);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

输出结果:

image-20220411043745211

2.浏览器一关闭,内存释放了,Cookie会话结束,如上,服务器不关闭,关闭浏览器,再访问同一个地址,不会出现时间

image-20220411105312949

image-20220411104602212

image-20220411104806726

3.将Cookie数据持久化---存到硬盘(设置)

image-20220411105142566

image-20220411105231866

image-20220411105755121

实现:

image-20220411110318005

输出结果:

image-20220411111034055

image-20220411111236006

补充:应该不会加一秒,如果速度够块,是不会加1秒的

4.路径名决定是否带Cookie

image-20220411113516331

image-20220411114628729

image-20220411115227075

CookieDemo1代码与CookieDemo2一致:

package com.xu.cookieAndsession;

import javafx.scene.chart.PieChart;

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 java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.IOException;
import java.util.Calendar;

/**
 * @auther xu
 * @date 2022/4/11 - 3:38
 */
public class CookieDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //创建一个输出流对象
        PrintWriter out= null;

        try {
            //指定服务器端解码方式
            resp.setCharacterEncoding("UTF-8");
            out = resp.getWriter();
            //获取客户端Cookied最后一次访问的时间
            //1.获取该cookie数组(一个服务器在客户端缓存中最多保存20个Cookie)
            Cookie[] cookies = req.getCookies();

            //2.遍历cookie数组
            for (int i = 0; cookies != null && i < cookies.length; i++) {//客户端第一次访问服务器时request对象中不会携带Cookie
                if ("lastAccessTime".equals((cookies[i].getName()))) {
                    String value = cookies[i].getValue();
                    //2.将得到的时间格式化
                    long l = Long.parseLong(value);
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String format = simpleDateFormat.format(l);

                    //3.响应给客户端
                    out.write(format);
                }
            }
            //4.创建cookie对象
            Cookie lastAccessTime = new Cookie("lastAccessTime", System.currentTimeMillis() + "");

            //4-1:设置Cookie的有效时间为(以秒为单位)
            lastAccessTime.setMaxAge(60*5);//设置cookie的保存时间为5分钟

            //5.将Cookie响应给客户端,更新客户端缓存
            resp.addCookie(lastAccessTime);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

该种路径也行(也会携带cookie):

image-20220411115649435

image-20220411115624405

image-20220411120101417

image-20220411120042194

1.调用方法设置path,只要在该路径下访问Servlet页面,浏览器都需要携带cookie

image-20220411121216928

image-20220411121242025

image-20220411121146574

补充反例:

image-20220413072838008

image-20220413072814646

image-20220413072752487

5.cookie存入中文时,需要使用的编码与解码

image-20220411155622668

6.删除cookie

image-20220411162001110

image-20220411162150300

通过在CookieClearnDemo类创建cookie对象,并将setMaxAge(0),设置为0,相当于删除Cookie,响应给客户端,更新cookie

image-20220411162818631

CookieClearnDemo类:

package com.xu.cookieAndsession;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @auther xu
 * @date 2022/4/11 - 13:49
 */

public class CookieClearnDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建一个Cookie
        Cookie ck = new Cookie("lastAccessTime", "");
        //明确删除那一条路径下的cookie,"/"代表删除"/secondServlet"路径下的所有cookie
        ck.setPath("/");
        ck.setMaxAge(0);//设置为0,相当于删除Cookie
        response.addCookie(ck);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

CookieDemo1与CookieDemo2代码一样:

package com.xu.cookieAndsession;

import javafx.scene.chart.PieChart;

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.xml.crypto.Data;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.IOException;
import java.util.Calendar;

/**
 * @auther xu
 * @date 2022/4/11 - 3:38
 */
public class CookieDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //创建一个输出流对象
        PrintWriter out= null;

        try {
            //指定服务器端解码方式
            resp.setCharacterEncoding("UTF-8");
            out = resp.getWriter();
            //获取客户端Cookied最后一次访问的时间
            //1.获取该cookie数组(一个服务器在客户端缓存中最多保存20个Cookie)
            Cookie[] cookies = req.getCookies();

            //2.遍历cookie数组
            for (int i = 0; cookies != null && i < cookies.length; i++) {//客户端第一次访问服务器时request对象中不会携带Cookie
                if ("lastAccessTime".equals((cookies[i].getName()))) {
                    String value = cookies[i].getValue();
                    //2.将得到的时间格式化
                    long l = Long.parseLong(value);
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String format = simpleDateFormat.format(l);

                    //3.响应给客户端
                    out.write(format);
                }
            }

            //4.创建cookie对象
            Cookie lastAccessTime = new Cookie("lastAccessTime", System.currentTimeMillis() + "");

            //4-1:设置Cookie的有效时间为(以秒为单位)
            lastAccessTime.setMaxAge(60*5);//设置cookie的保存时间为5分钟

            //4-2:调用方法设置path,只要在该路径下访问Servlet页面,浏览器都需要携带cookie
//            lastAccessTime.setPath("/secondServlet");
//            lastAccessTime.setPath(req.getContextPath());
            lastAccessTime.setPath("/");

            //5.将Cookie响应给客户端,更新客户端缓存
            resp.addCookie(lastAccessTime);


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

xml:

image-20220411163318850

4.记住用户名

xml:

image-20220411222113168

loginServlet.java:

package com.xu.test;

import com.sun.xml.internal.ws.transport.http.HttpAdapter;

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 java.io.IOException;
import java.io.PrintWriter;

/**
 * @auther xu
 * @date 2022/4/11 - 19:01
 */
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        String userName = "";
        String checked = "";
        //得到客户端保存的Cookie数据
        Cookie[] cookies = req.getCookies();
        for (int i = 0;cookies != null && i < cookies.length; i++) {
            if ((cookies[i].getName()).equals("userName")) {
                userName = cookies[i].getValue();
                checked = "checked='checked'";
            }
        }
        out.write("<form action='"+req.getContextPath()+"/servlet/doLogin' method='post'>");
        out.write("用户名:<input type='text' name='userName' value='"+userName+"'/><br/>");
        out.write("密码:<input type='password' name='pwd'/><br/>");
        out.write("记住用户名:<input type='checkbox' name='remember' "+checked+"/><br/>");//如果cookie有数据,就会自动记住用户名
        out.write("<input type='submit' value='登录'/><br/>");
        out.write("</form>");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

doLoginServlet.java:

package com.xu.test;

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 java.io.IOException;
import java.io.PrintWriter;

/**
 * @auther xu
 * @date 2022/4/11 - 21:17
 */
public class DoLoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //保证编码,解码一致性
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        //1.获取表单数据
        String userName = req.getParameter("userName");
        String password = req.getParameter("pwd");
        String remember = req.getParameter("remember");

        Cookie ck= new Cookie("userName", userName);//创建cookie对象
        ck.setPath("/");//设置在当前应用下操作cookie

        //2.处理业务逻辑
        //3.分发转向
        if ("Tom".equals(userName) && "123".equals(password)) {
            if (remember != null) {
                ck.setMaxAge(Integer.MAX_VALUE);//相当将cookie永久保存
            } else {
                ck.setMaxAge(0);//将cookie删除
            }
            resp.addCookie(ck);//将cookie响应给客户端
            out.write("登录成功!");
        } else {
            out.write("登录失败!");
            resp.setHeader("refresh","2;url="+req.getContextPath()+"/servlet/login");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       this.doGet(req,resp);
    }
}

操作结果:

image-20220411222612810

image-20220411222717735

关闭浏览器,再一次登录

image-20220411223015963

image-20220411223224382

image-20220411223250463

再一次登录,因为没有cookie,所以userName,checked不会自动填充

image-20220411223417373

image-20220412063923407

image-20220412064004908

5.历史记录思路分析:(没太听懂)

image-20220411230826848

6.历史记录的实现

image-20220412101251427

Book.java:

package com.xu.entity;

/**
 * @auther xu
 * @date 2022/4/12 - 6:45
 */
public class Book {
    private String id;
    private String name;
    private int price;
    private String anthor;

    public Book(String id, String name, int price, String anthor) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.anthor = anthor;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getAnthor() {
        return anthor;
    }

    public void setAnthor(String anthor) {
        this.anthor = anthor;
    }

    @Override
    public String toString() {
        return "Book{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", price=" + price +
                ", anthor='" + anthor + '\'' +
                '}';
    }
}

DButil.java:

package com.xu.util;

import com.xu.entity.Book;

import java.util.HashMap;
import java.util.Map;

/**
 * @auther xu
 * @date 2022/4/12 - 6:55
 */
public class DButil {
    private static Map<String, Book> books = new HashMap<>();
    static {
        books.put("1",new Book("1","三国演义",30,"罗贯中"));
        books.put("2",new Book("1","红楼梦",40,"曹雪芹"));
        books.put("3",new Book("1","水浒传",30,"施耐庵"));
        books.put("4",new Book("1","西游记",30,"吴承恩"));
    }
    //得到所有书的map集合
    public static Map<String,Book> findAllBooks() {
        return books;
    }

    /**
     * 根据id查找指定的书
     * @param id
     * @return
     */
    public static Book findBookById(String id) {
        return books.get(id);
    }

}

ShowAllBooksServlet.java:

package com.xu.history;

import com.xu.entity.Book;
import com.xu.util.DButil;

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 java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

/**
 * @auther xu
 * @date 2022/4/12 - 7:09
 */
public class ShowAllBooksServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //指定服务器编码,解码方式
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        out.write("本网站的书:<br/>");
        Map<String, Book> books = DButil.findAllBooks();
        for (Map.Entry<String,Book> book: books.entrySet()) {

            //target='_blank':跳转到商品详情页面打开一个新窗口
            out.write("<a href='"+req.getContextPath()+"/servlet/BookDetail?id="+book.getKey()+"' target='_blank'>"+book.getValue().getName()+"</a><br/>");
        }



        out.print("<hr/>最近浏览过的书:<br/>");
        Cookie[] cookies = req.getCookies();
        for (int i = 0; cookies != null && i < cookies.length; i++) {
            if ("historyBookId".equals(cookies[i].getName())) {//判断是否有historyBookId的key的cookie
                String value = cookies[i].getValue();//1-2-3
                String[] ids = value.split("-");
                for (int j = 0; j < ids.length; j++) {
                    Book book = DButil.findBookById(ids[j]);
                    out.print(book.getName()+"<br/>");
                }
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

ShowBookDetail.java:

package com.xu.history;

import com.xu.entity.Book;
import com.xu.util.DButil;

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 java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;

/**
 * @auther xu
 * @date 2022/4/12 - 7:28
 */
public class ShowBookDetail extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //指定服务器编码,解码方式
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();

        //通过Id获取书的详细信息
        String id = req.getParameter("id");
        Book book = DButil.findBookById(id);
        out.print(book);//因为write()方法只能够输出字符串

        //将浏览过的书id返回给客户端
        String historyBookId = organizedId(id,req);
        Cookie ck = new Cookie("historyBookId", historyBookId);
        ck.setMaxAge(Integer.MAX_VALUE);
        resp.addCookie(ck);

    }

    /**
     *客户端                         showAllBooks                             showBookDetail
     * 没有Cookie                         1                                  historyBookId=1
     * 有Cookie,但是没有historyBookId      1                                  historyBookId=1
     * historyBookId=1                   2                                  historyBookId=2-1
     * historyBookId=1-2                 2                                  historyBookId=2-1
     * historyBookId=1-2-3               2                                  historyBookId=2-1
     * historyBookId=1-2-3               4                                  historyBookId=4-1-2
     */
    private String organizedId(String id, HttpServletRequest req) {
        Cookie[] cookies = req.getCookies();
        if (cookies == null) {
            return id;
        }

        //查找有没有name叫做historyBookId的cookie
        Cookie historyBook = null;
        for (int i = 0; i < cookies.length;i++) {
            if ("historyBookId".equals(cookies[i].getName())) {
                historyBook = cookies[i];
            }
        }

        //如果没有historyBookId的cookie,则还返回id
        if (historyBook==null) {
            return id;
        }

        //对应已经有historyBook
        String value = historyBook.getValue();//2-1-3
        String[] values = value.split("-");//将字符串以"-"进行切割
        LinkedList<String> list = new LinkedList<>(Arrays.asList(values));//创建被切割的单个字符一个链表形式

        if (list.size() < 3) {//1 2
            if (list.contains(id)) {
                list.remove(id);//再一次访问id=2的书,如果原先历史记录有id=2,就将2在链表中移除,再在链表头部插入id=2(2->1)
            }
        } else {
            if (list.contains(id)) {//1 2 3
                list.remove(id);//再一次访问id=2的书,如果原先历史记录有id=2,就将2在链表中移除,再在链表头部插入id=2(2->1->3)
            } else {//1 2 3
                list.removeLast();//3本书都不是同一个id,移除最后一个Id,再在链表头部插入id=4(4->1->2)
            }
        }

        list.addFirst(id);//最新书的id添加到最前面


        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < list.size(); i++) {
            if (i>0) {
                sb.append("-");
            }
            sb.append(list.get(i));
        }
        System.out.println(sb);//1-2-3
        return sb.toString();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

测试结果:

image-20220412102514016

image-20220412102600753

image-20220412102224079

image-20220412102333839

2.session

1.HttpSession对象原理

image-20220412103710714

1.作用域

HttpSession作用域比Request大,比getContext()作用域小:

如果访问的是Context作用域:

一个浏览器窗口访问该Context作用域的数据,开启另一个浏览器窗口也访问访问Context作用域对象(application),这两个浏览器窗口

数据是共享的

如果访问的是Session作用域:

一个浏览器窗口访问Session作用域的数据,开启另一个浏览器窗口访问Session作用域的数据,这两个浏览器窗口都是访问在服务器端

各自的Session数据,数据不是共享的.只要窗口不关,访问多个Servlet,都可以共享该窗口的Session数据

如果访问的是Request作用域:

一次请求之内的可以共享Request数据,下一次经过了服务器端响应数据的回传会导致下一次发送请求时数据更新

image-20220412111956349

image-20220412111826158

image-20220412111929820

image-20220412111351735

image-20220412111709383

image-20220412112043086

更改一下:直接输出到浏览器

image-20220412112806471

image-20220412112837271

2.浏览器如何实现一个Session为一个用户浏览器服务?

image-20220412113751766

3.在同一个浏览器窗口之下,查看一下不同servlet页面所对应的Session所对应的Id是否相同

image-20220412115309754

image-20220412115322036

image-20220412115001512

image-20220412115255977

image-20220412115701770

2.购物车功能的实现:

image-20220412142215893

xml:

image-20220412160448951

ShowAllBookServlet.java:

package com.xu.shoppingCar;

import com.xu.entity.Book;
import com.xu.util.DButil;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;


/**
 * @auther xu
 * @date 2022/4/12 - 14:38
 */
public class ShowAllBookServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        out.print("该网站下有以下好书:<br/>");
        Map<String, Book> allBooks = DButil.findAllBooks();
        for (Map.Entry<String,Book> book:allBooks.entrySet()) {
            out.print("<a href='"+req.getContextPath()+"/servlet/addCar?id="+book.getKey()+"'>"+book.getValue().getName()+"</a><br/>");
        }
        out.print("<a href='"+req.getContextPath()+"/servlet/showShopCar'>查看购物车</a>");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

AddShoppCar.java:

package com.xu.shoppingCar;

import com.xu.entity.Book;
import com.xu.util.DButil;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * @auther xu
 * @date 2022/4/12 - 14:52
 */
public class AddShoppCar extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        //根据id得到书
        String id = req.getParameter("id");
        Book book = DButil.findBookById(id);

        //得到session对象
        HttpSession session = req.getSession();

        //从Session中取出list(购物车)
        List<Book> list = (List<Book>)session.getAttribute("ShoppingCar");
        if (list == null) {
            list = new ArrayList<Book>();
        }
        list.add(book);
        session.setAttribute("ShoppingCar",list);//把list添加到Session域中

        out.print("购买成功,将跳转到主页面");
        resp.setHeader("refresh","2;url="+req.getContextPath()+"/servlet/showAllBook");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

ShowShoppingCar.java:

package com.xu.shoppingCar;

import com.xu.entity.Book;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * @auther xu
 * @date 2022/4/12 - 15:07
 */
public class ShowShoppingCar extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();

        //得到Session对象
        HttpSession session = req.getSession();
        List<Book> books = (List<Book>)session.getAttribute("ShoppingCar");
        if (books==null) {
            out.print("你还什么都没买");
            //设置2秒钟后跳转
            resp.setHeader("refresh","2;url="+req.getContextPath()+"/servlet/showAllBook");
            return;
        }
        for (Book book:books) {
            out.print(book.getName()+"<br/>");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

test结果:

什么都没买:

image-20220412160809287

image-20220412160826534

买了书:

image-20220412160903800

image-20220412160933940

买了如下3本书:image-20220412161008442

重复买,会导致重名:(待解决)

image-20220412161427591

报错:

image-20220412154515859

原因:

image-20220412154751033

3.HttpSessionAPI:

补充:

1.Session依赖于cookie(因为Session的id存储在cookie中)

2.保存用户登录的信息一般往Session中放

image-20220412162603761

3.Session存活时间的设定--session.setMaxInactiveInterval(20);//20s

image-20220412163849311

image-20220412163729426

image-20220412163952316

4.Session对象的销毁

image-20220412164257305

3.内部原理

image-20220412165323684

找不到:

1.(浏览器默认Session存活时间为30分钟),浏览器并没有将cookie存入硬盘,浏览器没关(保证cookie存活),服务器也没关,但是人在半小时后再回来浏览网页,虽然请求头中仍然有关于Session的Id,但是此时HttpSession对象已经销毁了,通过该Id去寻找Session域,找不到,就从步骤2开始。

补充方法(不常用)

image-20220412170207332

4.session状态

image-20220412170827880

image-20220412171109623

注意:序列化(钝化)之后,用户的数据将从内存中保存到硬盘,反序列化(激活)时又可以将数据加载进来,关闭服务器也无妨(有疑问)

image-20220412181354429

5.客户端禁用Cookie后的会话数据保存问题

1.问题:

image-20220412183016392

image-20220412184140338

image-20220412184040610

image-20220412184854132

image-20220412185254954

2.解决:重写url

image-20220412191326796

image-20220412191401667

image-20220412191432560

image-20220412191829953

image-20220412191929403

image-20220412192128184

image-20220412192337284

解决原理:我们可以观察到,url后面的jsessionid的编号是一样的,代表是服务器端同一个Session对象,应该是将该Session对象编号在响应报文与请求报文中进行传递,通过直接访问该编号对应的Session域,达到访问在Session对象中存储的数据的目的(即使请求头中没有cookie类型 的数据)。

posted @ 2022-04-12 19:33  远道而重任  阅读(0)  评论(0编辑  收藏  举报