Cookie和Session

用户通过浏览器访问Web应用时,通常情况下,服务器需要对用户的状态进行跟踪。例如,用户在网站结算商品时,Web服务器必须根据请求用户的身份,找到该用户所购买的商品,在Web开发中,服务器跟踪用户信息的技术称为会话技术。

       两人通电话,一连串的你问我答就是的过程就是一个会话,Web应用中的会话过程类似于生活中的打电话过程,即指一个客户端(浏览器)与Web服务器之间连续发生的一系列请求和响应过程。

    用户甲和用户乙分别登录了购物网站,甲购买了一个粪叉手机,乙购买了一个平板,当他们结账时,Web服务器根据甲乙的信息分别进行保存,我们知道HttpServletRequest对象和ServletContext对象都可以对数据进行保存,但是他们都做不到,为什么?

    (1)客户端请求Web服务器时,针对每次HTTP请求,Web服务器都会创建一个HttpServletRequest对象,该对象只能保存本次请求所传递的数据,由于购买和结账是两个不同的请求,因此再发送结账请求时,之前购买请求中的数据会丢失。

    (2)使用ServletContext对象保存数据时,由于一个Web应用共享的是同一个ServletContext对象,因此,当用户发送结账请求时,由于无法区分哪些商品时哪个用户的所购买的,而会将该购物网站中所有用户购买的商品进行结算,这不成了冤大头了。

      因此,为了保存会话过程中产生的数据,在Servlet技术中,提供了两个用于保存会话数据的对象,分别是Cookie和Session。

 

Cookie

    Cookie是一种会话技术,它用于将会话过程中的数据保存到用户的浏览器中,从而使浏览器和服务器可以更好地进行数据交互。

举个例子,上超市,有会员卡,卡上记录个人信息如姓名,电话,超市根据卡的积分来进行优惠。Cookie的功能就好比于这张会员卡,当用户通过浏览器访问Web服务器时,服务器会给客户端(浏览器)发送一些信息,这些信息就保存在Cookie中。当浏览器再次访问服务器,都会在请求头中将Cookie发送给服务器,方便服务器对浏览器做出正确的响应。

     服务器向客户端发送Cookie时,会在HTTP响应头字段中增加Set-Cookie响应头字段。格式如下Set-Cookie: user = itcast;Path=/;

user是Cookie的名称,itcast表示Cookie的值,Path表示Cookie的属性。Cookie必须以键值对存在,其属性可以有多个,属性之间用分号和空格隔开。

Cookie和Session_第1张图片

当用户(客户端浏览器)第一次访问服务器,服务器会在响应消息中增加Set-Cookie头字段,将用户信息以Cookie的形式发送给浏览器。然后浏览器将接受的服务器发回的Cookie信息保存在浏览器的缓冲区中。

用户第二次访问该服务器时,都会在请求消息中将用户信息以Cookie的形式发送给Web服务器,从而使服务器端分辨出当前请求是由哪个用户发出的。

Cookie API

为了封装Cookie信息,在Servlet API中提供了一个javax.servlet.http.Cookie类,该类包含了生成Cookie信息和提取Cookie信息的各个属性的方法。

我们结合具体例子说

打开eclipse,新建web项目,在java Resource目录下,新建Servlet文件,

Cookie和Session_第2张图片

Cookie和Session_第3张图片

Cookie和Session_第4张图片

Cookie和Session_第5张图片

package t;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 *该类主要用于实现获取Cookie信息并将当前时间作为Cookie值发送给客户端。
 */
public class LastAccessServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		指定服务器输出内容的编码格式UTF-8,防止发生乱码
		response.setContentType("text/html;charset=utf-8");
//		创建变量上一次时间,赋予初值为空
		String lastAccessTime = null;
//		获取所有的cookie,并将这些cookie存放在数组中,是服务器请求时发过来的
		Cookie[] cookies = request.getCookies();
//		遍历cookies数组
		for(int i =0;cookies != null&& i

结果如下,第一次执行,所以没有Cookie,也就是为空,然后服务器要setCookie

Cookie和Session_第6张图片

第二次执行

Cookie和Session_第7张图片

但是当我们关闭浏览器,再次打开浏览器访问LastAccessServlet时,浏览器的显示结果为

Cookie和Session_第8张图片

这说明之前的浏览器存放的信息被删除了,因为默认情况下,Cookie对象的Max-Age属性的值为-1,即浏览器关闭后,删除这个Cookie对象。

为了让Cookie对象在客户端有较长的存活时间,可以通过setMaxAge()方法进行设置,例如将Cookie有效时间设置为1小时,增加的代码如下,cookie.setMaxAge(60*60)。

加在response.addCookie(cookie);前面即可

 

Session

     去医院就诊,有一张就诊卡,卡上只有卡号(相当于ID),没有其他信息,但病人每次去,只用出示就诊卡,医务人员便可以根据卡号查询到病人的信息。Session就是医院给病人的就医卡和医院为每个人保留档案的过程。

     当浏览器访问Web服务器时,Servlet容器就会创建一个Session对象和ID属性,其中,Session对象就相当于病历档案,ID相当于就诊卡号。当客户端后续访问服务器时,只要将标示号(ID)传递给服务器,服务器就能判断出该请求是那个客户端发出的,从而选择与之对应的Session对象为其服务。

      Cookie和Session_第9张图片

用户甲和用户乙都调用buyServlet将商品添加到购物车里,调用payServlet进行商品结算,当用户甲访问购物网站时,服务器为甲创建了一个Session对象(相当于购物车),set-Cookie:JSESSIONID =111,当甲将粪叉添加到购物车时,粪叉的信息便存储到了Session对象中,同时服务器将Session对象的 ID属性以Cookie(set-Cookie:JSESSIONID =111)的形式返回给甲的浏览器,当甲完成购物,进行结账时,需向服务器发送结账请求,这时,浏览器自动在请求消息头中将Cookie(set-Cookie:JSESSIONID =111)信息回送给服务器,服务器根据ID属性找到为用户甲所创建的Session对象,并将Session对象中所存放的粪叉信息取出进行结算。

实现购物车:

Cookie和Session_第10张图片

创建图书信息类

package cn.itcast.chapter05.session.example01;
import java.io.Serializable;
public class Book implements Serializable {
    private static final long serialVersionUID = 1L;
    private String id;
    private String name;
    public Book() {
    }
    public Book(String id, String name) {
            this.id = id;
            this.name = name;
        }
        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;
        }
    }


创建图数集合

package cn.itcast.chapter05.session.example01;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
public class BookDB {
private static Map books = new LinkedHashMap();
    static {
            books.put("1", new Book("1", "javaweb开发"));
            books.put("2", new Book("2", "jdbc开发"));
            books.put("3", new Book("3", "java基础"));
            books.put("4", new Book("4", "struts开发"));
            books.put("5", new Book("5", "spring开发"));
        }
        // 获得所有的图书
        public static Collection getAll() {
            return books.values();
        }
        // 根据指定的id获得图书
        public static Book getBook(String id) {
            return books.get(id);
        }
    }


显示所有图书

package cn.itcast.chapter05.session.example01;
import java.io.*;
import java.util.Collection;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class ListBookServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
            resp.setContentType("text/html;charset=utf-8");
            PrintWriter out = resp.getWriter();
            Collection books = BookDB.getAll();
            out.write("本站提供的图书有:
");
            for (Book book : books) {
                /*String url = "/chapter05/PurchaseServlet?id=" + book.getId();
                out.write(book.getName() + "点击购买
");//用超链接标签转到
*/
                String url = "/chapter05/PurchaseServlet?id=" + book.getId();
                HttpSession s=req.getSession();
                String newUrl=resp.encodeRedirectURL(url);
                out.write(book.getName() + "点击购买
");
            }

        }
    }


用户购买的图书

 package cn.itcast.chapter05.session.example01;
 import java.io.IOException;
 import java.util.*;
 import javax.servlet.ServletException;
 import javax.servlet.http.*;
 public class PurchaseServlet extends HttpServlet {
     private static final long serialVersionUID = 1L;
     public void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
             // 获得用户购买的商品
             String id = req.getParameter("id");
             if (id == null) {
                 // 如果id为null,重定向到ListBookServlet页面
                 String url = "/chapter05/ListBookServlet";
                 resp.sendRedirect(url);
                 return;
             }
             Book book = BookDB.getBook(id);
             // 创建或者获得用户的Session对象
             HttpSession session = req.getSession();
             // 从Session对象中获得用户的购物车
             List cart = (List) session.getAttribute("cart");
             if (cart == null) {
                 // 首次购买,为用户创建一个购物车(List集合模拟购物车)
                 cart = new ArrayList();
                 // 将购物车存入Session对象
                 session.setAttribute("cart", cart);
             }
             // 将商品放入购物车
             cart.add(book);
             // 创建Cookie存放Session的标识号
             Cookie cookie = new Cookie("JSESSIONID", session.getId());
             cookie.setMaxAge(60 * 30);//设置有效时间
             cookie.setPath("/chapter05");
             resp.addCookie(cookie);
             // 重定向到购物车页面
             String url = "/chapter05/CartServlet";
//             resp.sendRedirect(url);
             String newurl=resp.encodeRedirectURL(url);
             resp.sendRedirect(newurl);

         }
     }


购物车

package cn.itcast.chapter05.session.example01;
import java.io.*;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class CartServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        // 变量cart引用用户的购物车
        List cart = null;
        // 变量pruFlag标记用户是否买过商品,初始值为true即购买过
        boolean purFlag = true;
        // 获得用户的session,HttpServletRequest.getSession(false) 等同于 如果当前Session没有就为null;
        HttpSession session = req.getSession(false);
        // 如果session为null,purFlag置为false
        if (session == null) {
            purFlag = false;//即没有购买过
        }
        else {
            // 获得用户购物车
            cart = (List) session.getAttribute("cart");
            // 如果用的购物车为null,purFlag置为false
            if (cart == null) {
                purFlag = false;
            }
        }
        /*
         * 如果purFlag为false,表明用户没有购买图书 重定向到ListServlet页面
         */
        if (!purFlag) {
            out.write("对不起!您还没有购买任何商品!
");
        } else {
            // 否则显示用户购买图书的信息
            out.write("您购买的图书有:
");
            double price = 0;
            for (Book book : cart) {
                out.write(book.getName() + "
");
            }
        }
    }
}

 

 

你可能感兴趣的:(Cookie和Session)