动态网站开发讲课笔记05:会话及会话技术

一、会话概述

  • 在日常生活中,从拨通电话到挂断电话之间的一连串的你问我答的过程就是一个会话。在打电话过程中,通话双方会有通话内容,同样,在客户端与服务器交互的过程中,也会产生一些数据。例如,用户甲和乙分别登录了购物网站,甲购买了一个iPhone手机,乙购买了一个iPad,当这两个用户结账时,Web服务器需要对用户甲和乙的信息分别进行保存。为了保存会话过程中产生的数据,Servlet提供了两个用于保存会话数据的对象,分别是Cookie和Session。

二、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属性可以有多个,属性之间用分号“;”和空格分隔。

3、Cookie操作示意图

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

(二)了解Cookie API

1、构造方法

  • Cookie类有且仅有一个构造方法,具体语法格式:public Cookie(java.lang.String name, java.lang.String value);
  • 在Cookie的构造方法中,参数name用于指定Cookie的名称,value用于指定Cookie的值。需要注意的是,Cookie一旦创建,它的名称就不能再更改,Cookie的值可以为任何值,创建后允许被修改。

2、常用方法

方法声明 功能描述
String getName() 用于返回Cookie的名称
void setValue(String newValue) 用于为Cookie设置一个新的值
String getValue() 用于返回Cookie的值
void setMaxAge(int expiry) 用于设置Cookie在浏览器客户机上保持有效的秒数
int getMaxAge() 用于返回Cookie在浏览器客户机上保持有效的秒数
void setPath(String uri) 用于设置该Cookie项的有效目录路径
String getPath() 用于返回该Cookie项的有效目录路径
void setDomain(String pattern) 用于设置该Cookie项的有效域
String getDomain() 用于返回该Cookie项的有效域
void setVersion(int v) 用于设置该Cookie项采用的协议版本
int getVersion() 用于返回该Cookie项采用的协议版本
void setComment(String purpose) 用于设置该Cookie项的注解部分
String getComment() 用于返回该Cookie项的注解部分
void setSecure(boolean flag) 用于设置该Cookie项是否只能使用安全的协议传送
boolean getSecure() 用于返回该Cookie项是否只能使用安全的协议传送

(1)setMaxAge(int expiry)方法和getMaxAge()方法

  • setMaxAge(int expiry)和getMaxAge()方法分别用于设置和返回Cookie在浏览器上保持有效的秒数。如果设置的值为一个正整数,浏览器会将Cookie信息保存在本地硬盘中。从当前时间开始,在没有超过指定的秒数之前,这个Cookie都保持有效,并且同一台计算机上运行的该浏览器都可以使用这个Cookie信息。如果设置值为负整数,浏览器会将Cookie信息保存在浏览器的缓存中,当浏览器关闭时,Cookie信息会被删除。如果设置值为0,则浏览器会立即删除这个Cookie信息。

(2)setPath(String uri)方法和getPath()方法

  • (String uri)方法和getPath()方法是针对Cookie的Path属性的。如果创建的某个Cookie对象没有设置Path属性,那么该Cookie只对当前访问路径所属的目录及其子目录有效。如果想让某个Cookie项对站点的所有目录下的访问路径都有效,应调用Cookie对象的setPath()方法将其Path属性设置为“/”。

(3)setDomain(String pattern)方法和getDomain()方法

  • setDomain(String pattern)方法和getDomain()方法是针对Cookie的domain属性的。domain属性用于指定浏览器访问的域。例如,泸职院的域为“lzy.edu.cn”。设置domain属性时,其值必须以“.”开头,如domain=.lzy.edu.cn。默认情况下,domain属性的值为当前主机名,浏览器在访问当前主机下的资源时,都会将Cookie信息发送给服务器(当前主机)。需要注意的是,domain属性的值不区分大小写。

(三)使用Cookie的语法

1、导入包

  • import = "javax.servlet.http.Cookie"

2、创建Cookie

  • Cookie newCookie = new Cookie("parameter", "value");
参数 含义
parameter 用于代表cookie的名称(key)
value 用于表示当前key名称所对应的值

3、写入Cookie

  • response.addCookie(newCookie)

三、Session对象

(一)什么是Session

1、Session对象

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

2、网站购物图解析

  • 为了使读者更好的理解Session,下面以网站购物为例,通过一张图描述Session保存用户信息的原理。
    在这里插入图片描述
  • 用户甲和用户乙都调用buyServlet将商品添加到购物车,调用payServlet进行商品结算。由于甲和乙购买商品的过程类似,在此,以用户甲为例进行详细说明。当用户甲访问购物网站时,服务器为甲创建了一个Session对象(相当于购物车)。当甲将iPhone手机添加到购物车时,iPhone手机的信息便存放到了Session对象中。同时,服务器将Session对象的ID属性以Cookie (Set-Cookie: JSESSIONID=111)的形式返回给甲的浏览器。当甲完成购物进行结账时,需要向服务器发送结账请求,这时,浏览器自动在请求消息头中将Cookie (Cookie: JSESSIONID=111)信息发送给服务器,服务器根据ID属性找到为用户甲所创建的Session对象,并将Session对象中所存放的iPhone手机信息取出进行结算。

3、Session的优点

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

(二)了解HTTPSession API

1、Session对象的getSession()方法

  • Session是与每个请求消息紧密相关的,为此,HttpServletRequest定义了用于获取Session对象的getSession()方法,该方法有两种重载形式。
方法 说明
public HttpSession getSession(boolean create) 根据传递的参数判断是否创建新的HttpSession对象,如果参数为true,则在相关的HttpSession对象不存在时创建并返回新的HttpSession对象,否则不创建新的HttpSession对象,而是返回null。
public HttpSession getSession() 相当于第一个方法参数为true时的情况,在相关的HttpSession对象不存在时总是创建新的HttpSession对象。需要注意的是,由于getSession()方法可能会产生发送会话标识号的Cookie头字段,所以必须在发送任何响应内容之前调用getSession()方法。

2、HttpSession接口中的常用方法

方法声明 功能描述
String getId() 用于返回与当前HttpSession对象关联的会话标识号
long getCreationTime() 用于返回Session创建的时间,这个时间是创建Session的时间与1970年1月1日00:00:00之间时间差的毫秒表示形式
long getLastAccessedTime() 用于返回客户端最后一次发送与Session相关请求的时间,这个时间是发送请求的时间与1970年1月1日00:00:00之间时间差的毫秒表示形式
void setMaxInactiveInterval(int interval) 用于设置当前HttpSession对象可空闲的以秒为单位的最长时间,也就是修改当前会话的默认超时间隔
boolean isNew() 判断当前HttpSession对象是否是新创建的
void invalidate() 用于强制使Session对象无效
ServletContext getServletContext() 用于返回当前HttpSession对象所属于的Web应用程序对象,即代表当前Web应用程序的ServletContext对象
void setAttribite(String name, Object value) 用于将一个对象与一个名称关联后存储到当前的HttpSession对象中
String getAttribute() 用于从当前HttpSession对象中返回指定名称的属性对象
void removeAttribute(String name) 用于从当前HttpSession对象中删除指定名称的属性

(三)Session的生命周期

1、Session生效

  • Sessinon在用户第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session。此外,还可调用request.getSession(true)强制生成Session。只访问HTML、IMAGE等静态资源并不会创建Session。

2、Session失效

(1)“超时限制”判断Session是否生效

  • Web服务器采用“超时限制”判断客户端是否还在继续访问。在一定时间内,如果某个客户端一直没有请求访问,那么,Web服务器就会认为该客户端已经结束请求,并且将与该客户端会话所对应的HttpSession对象变成垃圾对象,等待垃圾收集器将其从内存中彻底清除。反之,如果浏览器超时后,再次向服务器发出请求访问,那么,Web服务器会创建一个新的HttpSession对象,并为其分配一个新的ID属性。

(2)强制Session失效

  • 使用invalidate()方法可以强制使Session对象失效
HttpSession session = request.getSession();
session.invalidate(); // 注销该request的所有session

3、自定义Session失效时间

  • 默认的Session失效时间并不能满足我们的需求。这时我们需要自定义Session的失效时间,自定义Session的失效时间有3种情况。

(1)在项目的web.xml文件里配置

  • 在项目的web.xml文件中配置Session的失效时间
<session-config>
    <session-timeout>30</session-timeout>
</session-config>
  • 需要注意的是,在web.xml配置的Session失效时间默认是分钟,所以上述代码设置Session失效时间为30分钟。

(2)在Servlet程序中手动设置

  • 在Servlet程序中手动设置Session的失效时间
session.setMaxInactiveInterval(30 * 60); // 设置单位为秒,设置为-1永不过期