会话概述
- (1)客户端请求Web服务器时,针对每次HTTP请求,Web服务器都会创建一个utpServletRequest对象,该对象只能保存本次请求所传递的数据。由于购买和结账是五个不同的请求,因此,在发送结账请求时,之前购买请求中的数据将会丢失。
- (2)使用ServletContext对象保存数据时,由于同个 Web应用共享的是同一个SnietContext 对象,因此,当用户在发送结账请求时,由于无法区分哪些商品是哪个用所购买的,而会将该购物网站中所有用户购买的商品进行结算.这显然也是不可行的。为了保存会话过程中产生的数据,在Servlet技术中,提供了两个用于保存会话数据的对象,分别是Cookie和Session。
Cookie对象
- 当用户浏览器访问Web服务器时,服务器会给客户发送一些信息,这些信息保存在cookie中,这样当浏览器再次访问服务器时,都会在请求头中将Cookie发送给服务器,方便服务器对浏览器做出正确响应。
- 服务器向客户端发送Cookie时,会在HTTP响应字段中增加Set-Cookie响应头字段,Set-Cookie字段头中设置的Cookie会遵循一定的语法规则,如下:
Set-Cookie:user=itcast;Path=/;
上述实例中,user代表Cookie的名称,itcast表示Cookie的值Path表示Cookie的属性。
Cookie API
为了封装Cookie信息在Servlet API中提供了包含Cookie信息和提取Cookie信息各个属性的方法。
###构造方法
- Cookie仅有一个构造方法具体格式:
public Cookie(java.lang.String name,java.lang.String value)
在构造方法中,参数name用于指定Cookie的名称,value用于指定Cookie的值。需要注意的是,Cookie一旦被创建,它的名称就不能被更改,Cookie的值可以为任何值,创建后可更改。
Cookie类的常用方法
如下表:
项目 | Value |
---|---|
String getName() | 用于返回Cookie的名称 |
void setValue(String newValue) | 用于设置Cookie的值 |
String getValue() | 用于返回该Cookie的值 |
void setMaxAge(int expiry) | 用于设置Cookie在浏览器客户机上保存的有效秒数 |
int getMaxAge() | 用于获取Cookie在浏览器客户机上保存的有效秒数 |
void setPath(String uri) | 用于设置该Cookie项的有效目录路径 |
void setPath() | 用于返回该Cookie项的有效目录路径 |
void setDomain(String pattern) | 用于设置该Cookie项的有效域 |
String getDomain() | 用于返回该Cookie项的有效域 |
void setVersion(int v) | 用于设置该Cookie项采用的协议版本 |
int setVersion() | 用于返回用于返回该Cookie项采用的协议版本 |
voidsetComment(String purpose) | 用于设置该Cookie项的注解部分 |
String getComment() | 用于返回该Cookie项的注解部分 |
void setSecuire(boolean flag) | 用于设置该Cookie项是否只能使用安全协议传送 |
boolean getSecure() | 用于返回该Cookie项是否只能使用安全协议传送 |
方法解释:
1)setMaxAge(int expiry)和getMaxAge()方法
上面的两个方法用于设置和返回Cookie在浏览器客户机上保存的有效秒数。如果设置的值为一个正整数时,浏览器会将Cooike信息保存到本地硬盘中,从当前时间开始,在没有超过指定的秒数之前,Cookie都保持有效,并且同一台计算机运行该浏览器都可以使用cookie信息;如果设置为负整数,浏览器会将Cookie信息保存在缓存中,当浏览器关闭时,Cookie信息就会被删除;如果设置为0时,则表示通知浏览器立即删除这个Cookie信息。默认情况下,Max-Age属性值为-1。
2)void setPath(String uri)和void setPath()方法
上面两个针对于Cookie的Path属性的。如果创建某个Cookie对象没有设置Path属性,那么该Cookie只针对当前访问路径所属的目录及其子目录有效。如果想让某个Cookie项对站点的所有目录显得访问路径都有效,应调用Cookie对象的setPath()方法将其Path属性设置为"/"。
3)void setDomain(String pattern)和void setDomain()方法
- (8.5版本以下)
上面两个是针对cookie的Domain属性的,是用来指定浏览器的访问域。例如某域名为"itcast.cn",那么,当设置Domain属性是,其值必以“.”。开头例如:Domain=.itcast.cn。默认情况下Domain值为当前主机名,浏览器在访问当前主机资源时,会将Cookie信息送给服务器。) - (8.5版本以上)
1、必须是1-9、a-z、A-Z、. 、- (注意是-不是_)这几个字符组成
2、必须是数字或字母开头 (所以以前的cookie的设置为.itcast.cn 的机制要改为itcast.cn 即可)
3、必须是数字或字母结尾
解决之法: 升级处理cookie的domain的地方即可 由 (.itcast.cn 的机制要改为 itcast.cn )
注意:Domain属性值不区分大小
Cookie案例显示上次访问时间
代码如下:
package cn.itcast.chapter06.session.example;
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.text.SimpleDateFormat;
import java.util.Date;
@WebServlet("/cookie")
public class LastAccessServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
/*
设置一个Cookie的name:LastAccessTime
读取上次cookie的访问时间
*/
String LastAccessTime = null;
Cookie[] cookies = req.getCookies(); //获取Cookie并存放到cookie数组中
for (int i=0;cookies==null&&i<cookies.length;i++){
if ("LastAccess".equals(cookies[i].getName())){
//如果Cookie名称为LastAccess获取Cookie值
LastAccessTime = cookies[i].getValue();
break;
}
}
if (LastAccessTime==null){
resp.getWriter().print("你是首次访问本站!!");
}else{
resp.getWriter().print("你上次访问的时间为:"+LastAccessTime);
}
//创建cookie对象,将当前时间作为Cookie发给客户端
String currenttime = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(new Date());
Cookie cookie = new Cookie("LastAccess",currenttime);
cookie.setMaxAge(60*60);
cookie.setPath("/cookie");
//发送Cookie
resp.addCookie(cookie);
}
}
代码注释
cookie.setMaxAge(60*60);
在默认情况下,Cookie对象的Max-Age的属性值为-1,当浏览器关闭会删除Cookie对象,通过setMaxAge()方法进行设置,例如上面代码设置的时间为1小时。
cookie.SetPath("/cookie")
因为每个站点最多存放20个Cookie,因此在创建Cookie对象时一般会设置他的路径,例如上方代码
会在/cookie回送cookie信息。
Session对象
Cookie技术可以将用户的信息保存在各自的浏览器中,并且可以在多次请求下实现数据共享,但是如果传递信息比较多,使用Cookie技术显然明显会增大服务器端程序处理难度,这时,可以使用Session实现,Session是一种将会话技术保存到服务端的技术。
HttpSession API
Session是将每个请求消息密切相关的,为此,HttpServletRequest定义了用于获取Session对象的getSession()方法,该方法有两种重载形式,如下:
public Httpsession getSession(boolean create)
public Httpsession getSession()
上面重载的两个方法都用于返回与当前请求相关的Httpsessioi对象。不同的是,第一个getSession()方法根据传递的参数来判断是否创建新的getSession对象,如果参数为true.则在相关的getSession对象不存在时创建并返回新的HttpSession 对象,否则不创建新的HttpSession对象,而是返回null.第二个getSession()方法则相当于第-一个方法参数为true时的情况,在相关的HttpSession 对象不存在时总是创建新的HttpSession对象。需要注意的是,由于getSession()方法可能会产生发送会话标识号的Cookie头字段,因此必须在发送任何响应内容之前调用getSession()方法。
要想使用HttpSession对象管理会话数据,不仅需要获取到HttpSession对象,还需要了解HttpSession对象的相关方法。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 对象可空闲的以秒为单位的最长时间,也就是修改当前会话的默认超时间隔
void invalidate( )| 用于强制使Session对象无效
boolean isNew()| 判断当前HttpSession对象是否是新创建的
ServletContext getServletContext()| 用于返回当前HttpSession对象所属于的Web应用程序对象,即代表当前Web应用程序的ServletContext对象
void setAttribute(String name ,Object value)| 用于将一个对象与一个名称关联后存储到当前的HttpSession对象中
String getAttribute()| 用于从当前HttpSession对象中返回指定名称的属性对象
void removeAttribute(String name)| 用于从当前HttpSession对象中删除指定名称的属性
[上一章(servlet必备知识)](https://blog.csdn.net/xiao_yan_/article/details/107758524)