一、学习目标
- 本节学习目标
- 了解什么是Cookie
- 掌握Cookie对象的使用
- 了解什么是Session
- 掌握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
类