会话技术 Cookie和Session(长达两万字总结)

本文详细介绍了Cookie和Session的工作流程、API、使用细节及其在会话跟踪中的应用。Cookie是客户端会话技术,而Session是服务器端会话技术。文章通过实例展示了如何使用Cookie和Session实现用户登录时间记录、浏览历史等功能,同时对比了两者在安全性、存储位置和生命周期等方面的差异。最后探讨了Cookie与Session的关系,强调了实践的重要性。
摘要由CSDN通过智能技术生成

目录

Cookie 的工作流程

 Cookie API

Cookie 的使用细节

Cookie 的缺点

显示上次浏览过商品

 思路:

Cookie的应用 

显示用户上次访问的时间

显示用户的浏览记录

 Session

Session 的工作原理

Session 与 Cookie 对比

Session API

Session 的生命周期

Session 对象在容器第一次调用 request.getSession() 方法时创建。

Session 对象销毁

Session 域对象

使用Session完成简单 的购物功能

纸上得来终觉浅,绝知此事要躬行。

话不多说开搞


Http协议无状态

无状态主要指 2 点:

  1. 协议对于事务处理没有记忆能力,服务器不能自动维护用户的上下文信息,无法保存用户状态;
  2. 每次请求都是独立的,不会受到前面请求的影响,也不会影响后面的请求。


当浏览器发送 HTTP 请求到服务器时,服务器会响应客户端的请求,但当同一个浏览器再次发送请求到该服务器时,服务器并不知道它就是刚才那个浏览器,即 HTTP 协议的请求无法保存用户状态。

通常情况下,用户通过浏览器访问 Web 应用时,服务器都需要保存和跟踪用户的状态。例如,用户在某购物网站结算商品时,Web 服务器必须根据请求用户的身份,找到该用户所购买的商品。由于 HTTP 协议是无协议的,无法保存和跟踪用户状态,所以需要其他的方案来解决问此题,它就是会话技术。

Cookie 属于客户端会话技术,它是服务器发送给浏览器的小段文本信息,存储在客户端浏览器的内存中或硬盘上。当浏览器保存了 Cookie 后,每次访问服务器,都会在 HTTP 请求头中将这个 Cookie 回传给服务器。

Cookie分为两种:

  1. 会话级别 Cookie(默认):Cookie 保存到浏览器的内存中,浏览器关闭则 Cookie 失效。
  2. 持久的 Cookie:Cookie 以文本文件的形式保存到硬盘上。

Cookie 的工作流程

Cookie 是基于 HTTP 协议实现的,工作流程如下。

  1. 客户端浏览器访问服务器时,服务器通过在 HTTP 响应中增加 Set-Cookie 字段,将数据信息发送给浏览器。
  2. 浏览器将 Cookie 保存在内存中或硬盘上。
  3. 再次请求该服务器时,浏览器通过在 HTTP 请求消息中增加 Cookie 请求头字段,将 Cookie 回传给 Web 服务器。服务器根据 Cookie 信息跟踪客户端的状态。

 Cookie API

javax.servlet.http 包中定义了一个 Cookie 类,利用它的带参构造方法,可以创建 Cookie 对象。例如:

  • Cookie c = new Cookie("url", "www.biancheng.net");

HttpServletResponse 接口和 HttpServletRequest 接口也都定义了与 Cookie 相关的方法,如下表所示。

方法 描述 所属接口
void addCookie(Cookie cookie) 用于在响应头中增加一个相应的 Set-Cookie 头字段。 javax.servlet.http.HttpServletResponse
Cookie[] getCookies() 用于获取客户端提交的 Cookie。 javax.servlet.http.HttpServletRequest

javax.servlet.http.Cookie 类中提供了一系列获取或者设置 Cookie 的方法,如下表。

Cookie 的使用细节

使用 Cookie 开发时需要注意以下细节:

  • 一个 Cookie 只能标识一种信息,它至少包含一个名称(NAME)和一个值(VALUE)。
  • 如果创建了一个 Cookie,并发送到浏览器,默认情况下它是一个会话级别的 Cookie。用户退出浏览器就被删除。如果希望将 Cookie 存到磁盘上,则需要调用 setMaxAge(int maxAge) 方法设置最大有效时间,以秒为单位。
  • 使用 setMaxAge(0) 手动删除 Cookie时,需要使用 setPath 方法指定 Cookie 的路径,且该路径必须与创建 Cookie 时的路径保持一致。

 如果你想用cookie保存中文,那么就要使用Unicode字符时需要对Unicode字符进行编码,不然会报错,勤劳着可以试试QAQ。

Cookie cookie1=new Cookie("cun", URLEncoder.encode("我爱中国","UTF-8"));

我们在取出Cookie的时候要对中文数据进行解码 

String valu= URLDecoder.decode(cookie1[i].getValue(),"UTF-8");

Cookie 的缺点

Cookie 虽然可以解决服务器跟踪用户状态的问题,但是它具有以下缺点:

  • 在 HTTP 请求中,Cookie 是明文传递的,容易泄露用户信息,安全性不高。
  • 浏览器可以禁用 Cookie,一旦被禁用,Cookie 将无法正常工作。
  • Cookie 对象中只能设置文本(字符串)信息。
  • 客户端浏览器保存 Cookie 的数量和长度是有限制的。

 简单实现一下Cookie

package com.xxx;

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;


@WebServlet("/Test")
public class Test1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie1=new Cookie("cun","cunse");
        cookie1.setMaxAge(30);
        resp.addCookie(cookie1);
        req.getRequestDispatcher("/ServletDemo6").forward(req,resp);
    }

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

SerlvetDemo6

package com.xxx;

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;

/*
* 转发
* */
@WebServlet("/ServletDemo6")
public class ServletDemo6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ServletDemo6");
        Cookie[] cookies = req.getCookies();
        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                resp.getWriter().write(cookie.getName() + ":" + cookie.getValue());

            }
        }
    }

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

Cookie 主要用于下面三个目的

  • 会话管理 登陆、购物车、游戏得分或者服务器应该记住的其他内容

  • 个性化 用户偏好、主题或者其他设置

  • 追踪 记录和分析用户行为

了解Cookie之后我们就可以搞事情了

判断用户是不是第一次来的这个servlet如果是记录当前时间,下次访问输出上次登录的时间(切记在写SimpleDateFormat("yyyy-MM-ddHH:mm:ss"不用有空格不然会报错))

package com.xxx;

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

@WebServlet("/Test22")
public class Test22 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //格式化时间
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-ddHH:mm:ss");
        //设置编码
        resp.setContentType("text/html;charset=UTF-8");

        //获取网页上的Cookie
        Cookie[] cookies=req.getCookies();
        //判断cookie是否为空
        String cookieValue=null;
        for(int i=0;cookies!=null&&i<cookies.length;i++){
            //获取tine的cookie
            if(cookies[i].getName().equals("time")){
                resp.getWriter().write("你上次登录的时间是:");
                cookieValue=cookies[i].getValue();
                resp.getWriter().write(cookieValue);

                cookies[i].setValue(simpleDateFormat.format(new Date()));
                //覆盖上一次Cookie值
                resp.addCookie(cookies[i]);
                break;
            }
        }

        //判断Cookie的值是空的,那么就是第一次登录
        if(cookieValue==null){
            //创建一个Cook
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值