动态网站开发课程学习笔记05:回话及会话技术

本文介绍了Cookie和Session的概念及其在Web应用中的作用。Cookie作为客户端存储用户信息的方式,通过Set-Cookie响应头设置并在后续请求中携带。Session则在服务器端保存用户状态,提供更高的安全性。文中通过案例展示了如何在JavaServlet中使用Cookie记录用户访问时间,并对比了Cookie与Session的安全优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、学习目标

  1. 本节学习目标
  2. 了解什么是Cookie
  3. 掌握Cookie对象的使用
  4. 了解什么是Session
  5. 掌握Session对象的使用

二、Cookie对象

(一)什么是Cookie

  • 目标:了解什么是Cookie

1、Cookie的概念

在现实生活中,当顾客在购物时,商城经常会赠送顾客一张会员卡,卡上记录用户的个人信息(姓名,手机号等)、消费额度和积分额度等。顾客一旦接受了会员卡,以后每次光临该商场时,都可以使用这张会员卡,商场也将根据会员卡上的消费记录计算会员的优惠额度和累加积分。在Web应用中,Cookie的功能类似于会员卡,当用户通过浏览器访问Web服务器时,服务器会给客户端发送一些信息,如用户信息和商品信息,这些信息都保存在Cookie中。这样,当该浏览器再次访问服务器时,会在请求头中将Cookie发送给服务器,方便服务器对浏览器做出正确地响应。

2、如何设置Cookie

服务器向客户端发送Cookie时,会在HTTP响应头字段中增加Set-Cookie响应头字段。Set-Cookie头字段中设置的Cookie的具体示例:Set-Cookie: user=howard; path=/;
user表示Cookie的名称,howard表示Cookie的值,path表示Cookie的属性。Cookie必须以键值对的形式存在,Cookie属性可以有多个,属性之间用分号“;”和空格分隔。

2、Cookie操作示意图

当用户第一次访问服务器时,服务器会在响应消息中增加Set-Cookie头字段,将用户信息以Cookie的形式发送给浏览器。一旦用户浏览器接受了服务器发送的Cookie信息,就会将它保存在浏览器的缓冲区中,这样,当浏览器后续访问该服务器时,都会在请求消息中将用户信息以Cookie的形式发送给服务器,从而使服务器分辨出当前请求是由哪个用户发出的。

三、案例演示

1、创建Web项目

  • Web项目 - CookieDemo
    在这里插入图片描述
  • 设置项目名称与保存位置
    在这里插入图片描述
  • 单击【Finish】按钮
    在这里插入图片描述

2、修改Artifact名称,重新部署项目

  • 在项目结构窗口里修改Artifact名称
    在这里插入图片描述

3、创建LastAccessServlet类

-创建net.huawei.servlet包,然后在里面创建LastAccessServlet
在这里插入图片描述
LastAccessServlet类具体代码

package net.lxy.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import javax.xml.crypto.Data;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

@WebServlet(name = "LastAccessServlet", value = "/access")
public class LastAccessServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应对象内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取打印输出流
        PrintWriter out = response.getWriter();
        // 获取所有cookie
        Cookie[] cookies = request.getCookies();
        // 定义标志变量isFirstAccess
        boolean isFirstAccess = true;
        // 判断cookies是否为空
        if (cookies.length > 0 && cookies != null) {
            // 遍历cookies数组
            for (Cookie cookie:cookies){
                // 获取cookie名称
                String name = cookie.getName();
                // 判断cookie名称是否为‘lastTime’
                if (name.equals("lastTime")){
                    // 用户不是第一次访问
                    isFirstAccess = false;
                    // 获取cookie的值(上次访问时间)
                    String value = cookie.getValue();
                    // 控制台输出解码前的数据
                    System.out.println("编码前:" + value);
                    // 对cookie值进行URL解码
                    value = URLDecoder.decode(value,"utf-8");
                    // 控制台输出解码后的数据
                    System.out.println("解码后:" + value);
                    // 在页面显示用户上次访问时间
                    out.print("欢迎回来,您上次访问时间:" + value);
                    // 获取当前时间字符串,重新设置cookie
                    Date date = new Date();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                    String strDate = sdf.format(date);
                    // 控制台输出编码前的日期数据
                    System.out.println("编码前:" + strDate);
                    // 对日期数据进行URL编码
                    strDate = URLEncoder.encode(strDate,"utf-8");
                    // 控制台输出编码后的日期数据
                    System.out.println("编码后:" + strDate);
                    // 设置cookie的值以及属性
                    cookie.setValue(strDate);
                    // 设置cookie的存活时间(以秒为单位)
                    cookie.setMaxAge(30 * 24 * 60 * 60); // 一个月
                    // 加入cookie,让其生效
                    response.addCookie(cookie);
                }
            }
        }

        if (isFirstAccess){ // cookies为空,表明是第一次访问
            // 获取当前时间字符串,重新设置cookie
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            String strDate = sdf.format(date);
            // 控制台输出编码前的日期数据
            System.out.println("编码前:" + strDate);
            // 对日期数据进行URL编码
            strDate = URLEncoder.encode(strDate,"utf-8");
            // 控制台输出编码后的日期数据
            System.out.println("编码后:" + strDate);
            // 创建一个cookie
            Cookie cookie = new Cookie("lastTime",strDate);
            // 设置cookie的值以及属性
            cookie.setValue(strDate);
            // 设置cookie的存活时间(以秒为单位)
            cookie.setMaxAge(30 * 24 * 60 * 60); // 一个月
            // 加入cookie,让其生效
            response.addCookie(cookie);
            // 在页面显示欢迎用户首次访问的信息
            out.print("您好,欢迎你首次访问本网站");
        }

    }

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


}

4、启动服务器,查看结果

  • 启动服务器,访问http://localhost:8080/CookieDemo/access
    在这里插入图片描述
  • 关闭浏览器后,再次打开浏览器,访问LastAccessServlet,浏览器就显示了时间
    在这里插入图片描述

四、Session对象

(一)、什么是Session

  • 目标:了解什么是Session

1、Session对象

  • 当人们去医院就诊时,就诊病人需要办理医院的就诊卡,就诊卡上只有卡号,没有其他信息。但病人每次去该医院就诊时,只要出示就诊卡,医务人员便可根据卡号查询到病人的就诊信息。Session技术类似医院办理就诊卡和医院为每个病人保留病历档案的过程。当浏览器访问Web服务器时,Servlet容器就会创建一个Session对象和ID属性, Session对象就相当于病历档案,ID就相当于就诊卡号。当客户端后续访问服务器时,只要将ID传递给服务器,服务器就能判断出该请求是哪个客户端发送的,从而选择与之对应的Session对象为其服务。

2、Session的优点

  • Session还具有更高的安全性,它将关键数据保存在服务器。cookie则是将数据存在客户端的浏览器中。因此cookie是较为危险的,若客户端遭遇黑客攻击,cookie信息容易被窃取,数据也可能被篡改,而运用Session可以有效避免这种情况的发生。

(二)、Session案例演示 - 实现购物车

1、创建Web项目

创建Java Enterprise项目,添加Web Application
在这里插入图片描述

  • 设置项目名称与保存位置
    在这里插入图片描述
  • 单击【Finish】按钮
    在这里插入图片描述

2、修改Artifact名称,重新部署项目

  • 在项目结构窗口里修改Artifact名称
    在这里插入图片描述
  • 在服务期配置窗口里,重新部署项目
    在这里插入图片描述
    在这里插入图片描述

3、创建蛋糕实体类

  • 创建net.huawei.session.bean包,然后在包里创建Cake
    在这里插入图片描述
  • Cake类具体代码
package net.lxy.session.bean;

/**
 * 功能:蛋糕实体类
 * 作者:lxy
 * 日期:2023年04月21日
 */
public class Cake {
    private static final long serialVersionUID = 1L;
    private String id;
    private String name;

    public Cake() {
    }

    public Cake(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;
    }

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

4、创建蛋糕数据库模拟类

  • 创建net.huawei.session.dao包,然后在包里创建CakeDao类,用于模拟访问蛋糕数据库
    在这里插入图片描述
  • CakeDao类的具体代码
package net.lxy.session.bean;

/**
 * 功能:蛋糕实体类
 * 作者:lxy
 * 日期:2023年04月21日
 */
public class Cake {
    private static final long serialVersionUID = 1L;
    private String id;
    private String name;

    public Cake() {
    }

    public Cake(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;
    }

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

5、创建蛋糕列表处理程序

  • 创建net.huawei.session.servlet包,然后在包里创建CakeListServlet类,用于显示所有可购买蛋糕的列表,通过单击“购买”链接,便可将指定的蛋糕添加到购物车中
    在这里插入图片描述
  • CakeListServlet类的具体代码
package net.lxy.session.servlet;

import net.lxy.session.CakeDao.CakeDao;
import net.lxy.session.bean.Cake;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;

/**
 * 功能:显示蛋糕列表
 * 作者:lxy
 * 日期:2023年04月21日
 */
@WebServlet(name = "CakeListServlet", value = "/cake_list")
public class CakeListServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置相应体内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取字符输出流
        PrintWriter out = response.getWriter();
        // 获取蛋糕集合
        Collection<Cake> cakes = CakeDao.findAllCakes();
        // 在页面居中显示蛋糕列表
        out.print("<body style='text-align: center'>");
        out.print("<h3>本站提供的蛋糕</h3>");
        // 显示全部蛋糕
        for (Cake cake : cakes){
            // 定义点击购买超链接URL
            String url = "purchase?id=" + cake.getId();
            // 显示蛋糕信息与购买超链接
            out.print(cake.getId() +"" + cake.getName() +"<a href='"+url+"'>点击购买</a><br />");
        }
        out.print("</body>");
    }

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


}

  • 启动服务器,访问http://localhost:8080/SessionDemo/cake_list
    在这里插入图片描述
  • 但此时我们单击超链接会出现404错误,原因是我们的purchase还没有定义。
    在这里插入图片描述
  • 下面我们将对此问题进行解决

6、创建购物处理程序

  • net.huawei.session.servlet包里创建PurchaseServlet
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值