第四章:会话及其会话技术
OVERVIEW
在Web开发中,服务器跟踪用户信息的技术称为会话技术,
例如:用户在网站结算商品时,web服务器必须根据请求用户的身份,找到该用户所购买的商品(跟踪用户信息技术)。
Cookie与Session的引入:
在之前的学习中,可以知道HttpServletRequest
对象与ServletContext
对象都可以对数据进行保存,但都不采用的原因如下:
- 数据保存有效时长问题:针对每个HTTP请求Web服务器都会创建一个
HttpServletRequest
对象,该对象只能保存本次请求所传递的数据(之前的HTTP请求保存的数据将丢失)。 - 保存数据区分问题:由于同一个Web应用共享的是同一个
ServletContext
对象,因此当某个用户在发送结账请求时:无法区分下单商品对应的购买用户(将所有用户的所有下单商品进行结算)。
为了保存会话过程中产生的数据,在Servlet技术中提供了两个用于保存会话数据的对象:Cookie与Session
一、Cookie对象
1.Cookie概念
Cookie是一种会话技术,该技术将会话过程中产生的数据保存到用户的浏览器中,从而使浏览器和服务器可以进行更好的数据交互。
- 当用户通过浏览器访问Web服务器时,服务器会给客户端发送一些信息(这些信息都将被保存在Cookie中)。
- 当该浏览器再次访问Web服务器时,浏览器会在请求头中将Cookie发送给服务器(方便服务器对浏览器做出正确的响应)。
(1)Set-Cookie:
服务器向客户端发送Cookie时,会在HTTP响应头字段中增加Set-Cookie响应头字段如下所示:
Set-Cookie: author=HelloWorld999; Path=/;
/*
注解:
1.user表示Cookie的名称、itcast表示Cookie的值、Path表示Cookie的属性
2.Cookie必须要以键值对的形式存在
3.Cookie的属性可以有多个,其属性之间必须用分号 or 空格隔开
*/
(2)Cookie在浏览器与服务器间的传输过程:
- 当用户第一次访问服务器时,服务器会在响应消息中添加
Set-Cookie
头字段,将用户信息以Cookie形式发送给浏览器(保存在浏览器缓冲区中) - 当该浏览器再次访问Web服务器时,都会在其请求消息中将用户信息以
Cookie
的形式发送给Web服务器(解决保存数据区分问题)
2.Cookie API
在ServletAPI中提供了一个javax.servlet.http.Cookie
类,包含了生成Cookie信息和提取Cookie信息各个属性的方法(封装)。
(1)Cookie构造方法:
public Cookie(java.lang.String name, java.lang.String value)
/*
注释:
1.参数name为Cookie的名称
2.参数value用于指定Cookie的值
*/
注意:
Cookie
一旦创建,其名称name就不能更改,但值value可以为任何值且创建后允许修改
(2)Cookie类的常用方法:
在通过Cookie的构造方法创建Cookie对象之后,便可以使用该类的所有方法,Cookie常用方法如下:
point1:关于setMaxAge(int expiry)
和getMaxAge()
方法
这两个方法用于设置和返回Cookie在浏览器上保持有效的时间(秒),
- 如果设置的值为正数,浏览器会将Cookie信息保存在本地硬盘中;从当前时间开始持续Cookie保持有效,并且在同一台计算机上运行的浏览器都可以使用这个Cookie信息。
- 如果设置的值为负数,浏览器会将Cookie信息保存在缓存中(浏览器关闭时Cookie信息将被删除);
- 如果设置的值为0,则表示通知浏览器立即删除这个Cookie信息
注意:在默认情况下,Max-Age属性的值为-1
point2:关于setPath(String uri)
和getDomain()
方法
这两个方法用于设置和返回Cookie的Path
属性的,
- 如果创建的Cookie对象没有设置Path属性,那么该Cookie只对当前路径所属的目录及其子目录有效。
注意:如果想让某个Cookie项对站点的所有目录下的访问路径都有效,应调用Cookie对象的
setPath()
方法将Path
属性值设为/
point3:关于setDomain(String pattern)
和getDomain()
方法
这两个方法用于设置和返回Cookie的Domain
属性的,
- domain属性是用来指定浏览器访问的域,设置属性值时必须以
.
开头,如domain = .itcast.cn
补充:
- 默认情况下domain属性的值为当前主机名,浏览器在访问当前主机下的资源时,都会将Cookie信息回送给服务器
- domain属性的值是不区分大小写的
答案:A
3.Cookie案例:显示用户上次访问时间
package c5p1;
import java.io.IOException;
import java.util.Date;
import java.text.SimpleDateFormat;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class LastAccessServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String lastAccessTime = null;
//1.获取所有的Cookie,并将这些Cookie存放在数组中
Cookie[] cookies = request.getCookies();
//2.遍历cookies数组
for (int i = 0; cookies != null && i < cookies.length; ++i) {
if ("lastAccess".equals(cookies[i].getName())) {
//如果cookie的名称为lastAccess,则获取该cookie的值
lastAccessTime = cookies[i].getValue();
break;
}
}
//3.判断是否存在名称为lastAccess的cookie
if (lastAccessTime == null) {
response.getWriter().print("您是首次访问本站!");
} else {
response.getWriter().print("您上次访问的时间是:" + lastAccessTime);
}
//4.创建cookie,将当前时间作为cookie的值发送给客户端
String currentTime = new SimpleDateFormat("yyyy-MM-dd/hh:mm:ss").format(new Date());
Cookie cookie = new Cookie("lastAccess", currentTime);
//5.设置Cookie的有效时间为1小时(解决浏览器关闭Cookie数据立即丢失的问题)
//cookie.setMaxAge(60*60);
//6.发送cookie
response.addCookie(cookie);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
注意:cookie存储的值(这里为字符串类型)中不能含有空格,否则将出现Cookie值中存在无效字符报错,p148程序5-1存在疏漏
二、Session对象
1.Session概念
如果传递的信息较多,使用Cookie技术会增大服务器端程序处理的难度(Session技术很好的解决的这一问题),
Session是一种,将会话过程中产生的数据保存到服务器端的会话技术。
- 当用户通过浏览器访问Web服务器时,Servlet容器就会创建一个Session对象和ID属性(两者唯一对应)。
- 当该浏览器再次访问Web服务器时,将标识号(ID)传递给服务器,就能选择出对应的Session对象为其服务。
注意:由于客户端需要接收、记录和回送Session对象的ID,因此通常Session是借助Cookie技术来传递ID属性的。
2.HttpSession API
(1)Session对象获取:
public HttpSession getSession() //在相关对象不存在时,创建并返回新的HttpSession对象
public HttpSession getSession(boolean create) //在相关对象不存在时且参数值为true时,创建并返回新的HttpSession对象
注意:由于
getSession()
方法可能产生发送会话标识号的Cookie头字段,故必须在发送任何响应内容之前调用getSession()
方法
(2)Session接口常用方法:
3.Session超时管理
- 一定时间内,如果客户端一直没有请求访问,Web服务器将会认为客户端已结束请求并将对应的
HttpSession
对象变成垃圾对象。 - 在浏览器超时后,再次向服务器发出请求访问,Web服务器则会创建一个新的
HttpSession
对象并分配一个新ID属性。
在会话过程中,会话的有效时间可以在web.xml文件中进行设置(其默认值由Servlet容器定义),单位为分钟。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
补充:想要使Session失效,除了可以等待会话时间超时外,还可以通过
invalidate()
方法强制使会话失效