什么是cookie
在现实生活中,当顾客在购物时,商城经常会赠送顾客一张会员卡,卡上记录用户的个人信息(姓名,手机号等)、消费额度和积分额度等。顾客一旦接受了会员卡,以后每次光临该商场时,都可以使用这张会员卡,商场也将根据会员卡上的消费记录计算会员的优惠额度和累加积分。在Web应用中,Cookie的功能类似于会员卡,当用户通过浏览器访问Web服务器时,服务器会给客户端发送一些信息,如用户信息和商品信息,这些信息都保存在Cookie中。这样,当该浏览器再次访问服务器时,会在请求头中将Cookie发送给服务器,方便服务器对浏览器做出正确地响应。
cookie的概念
当用户第一次访问服务器时,服务器会在响应消息中增加Set-Cookie头字段,将用户信息以Cookie的形式发送给浏览器。一旦用户浏览器接受了服务器发送的Cookie信息,就会将它保存在浏览器的缓冲区中,这样,当浏览器后续访问该服务器时,都会在请求消息中将用户信息以Cookie的形式发送给服务器,从而使服务器分辨出当前请求是由哪个用户发出的。
Cookie API
构造方法
cookie类有且仅有一个构造方法,具体语法格式如下
public Cookie(java.lang.String name,java.lang.String value);
在Cookie的构造方法中,参数name用于指定Cookie的名称,value用于指定Cookie的值。需要注意的是,Cookie一旦创建,它的名称就不能再更改,Cookie的值可以为任何值,创建后允许被修改。
cookie类的常用方法
方法声明 | 功能描述 |
---|---|
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项是否只能使用安全的协议传送 |
setMaxAge(int expiry)方法和getMaxAge()方法
setMaxAge(int expiry)和getMaxAge()方法分别用于设置和返回cookie在浏览器上保持有效秒数 。如果设置的值为一个正整数,浏览器会将Cookie信息保存在本地硬盘中。从当前时间开始,在没有超过指定的秒数之前,这个Cookie都保持有效,并且同一台计算机上运行的该浏览器都可以使用这个Cookie信息。如果设置值为负整数,浏览器会将Cookie信息保存在浏览器的缓存中,当浏览器关闭时,Cookie信息会被删除。如果设置值为0,则浏览器会立即删除这个Cookie信息。
setPath(String uri)方法和getPath()方法
setPath(String uri)方法和getPath()方法是针对Cookie的Path属性的。如果创建的某个Cookie对象没有设置Path属性,那么该Cookie只对当前访问路径所属的目录及其子目录有效。如果想让某个Cookie项对站点的所有目录下的访问路径都有效,应调用Cookie对象的setPath()方法将其Path属性设置为“/”。
setDomain(String pattern)方法和getDomain()方法
setDomain(String pattern)方法和getDomain()方法是针对Cookie的domain属性的。domain属性用于指定浏览器访问的域。例如,我的博客的域为“qu1u1.cn”。设置domain属性时,其值必须以“.”开头,如domain=.qu1u1.cn。默认情况下,domain属性的值为当前主机名,浏览器在访问当前主机下的资源时,都会将Cookie信息发送给服务器(当前主机)。需要注意的是,domain属性的值不区分大小写。
✏️任务:显示用户上次访问时间
在IDEA中新建Web项目chapter05并添加Servlet-api.jar包,在chapter05项目的src包中编写一个名称为LastAccessServlet的Servlet类,该类主要用于获取Cookie信息中的时间并发送给客户端。主要代码如下:
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet(name = "LastAccessServlet",urlPatterns = "/LastAccessServlet")
public class LastAccessServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException,IOException {
//指定服务器输出内容的编码方式UTF-8,防止发生乱码
response.setContentType("text/html;charset=utf-8");
//获取所有cookie
Cookie[] cookies=request.getCookies();
//定义flag的boolean变量,用于判断cookies是否为空
boolean flag=false;
//遍历cookie数组
if(cookies.length >0&&cookies!=null){
for(Cookie cookie:cookies) {
//获取cookie的名称
String name=cookie.getName();
//判断名称是否是lastTime
if("lastTime".equals(name)){
//有该cookie不是第一次访问
flag=true;
//响应数据
//获取cookie的value时间
String value=cookie.getValue();
System.out.println("解码前:"+value);
//URL解码
value= URLDecoder.decode(value, "utf-8");
System.out.println("解码后:"+value);
response.getWriter().write("欢迎回来,您上次访问时间为:"+value);
//设置cookie的value
//获取当前时间的字符串,重新设置cookie的值,重新发送cookie
Date date=new Date();
SimpleDateFormat timesdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_time=timesdf.format(date);
System.out.println("编码前:"+str_time);
//URL编码
str_time=URLEncoder.encode(str_time, "utf-8");
System.out.println("编码后:"+str_time);
cookie.setValue(str_time);
//设置cookie存活时间
cookie.setMaxAge(60*60*24*30); //一个月
//加入当前cookie请求时间
response.addCookie(cookie);
break;
}
}
//如果cookies中没有时间,也就是没有访问过
if(cookies==null || cookies.length==0 || flag==false){
//设置cookie的value
//获取当前时间的字符串,重新设置cookie的值,重新发送cookie
Date date=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date=sdf.format(date);
System.out.println("编码前:"+str_date);
//URL编码
str_date= URLEncoder.encode(str_date,"utf-8");
System.out.println("编码后:"+str_date);
Cookie cookie=new Cookie("lastTime",str_date);
//设置cookie存活时间
cookie.setMaxAge(60*60*24*30);//一个月
response.addCookie(cookie);
response.getWriter().write("您好,欢迎您首次访问");
}
}
}
public void doPost(HttpServletRequest request,HttpServletResponse
response)throws ServletException,IOException{
this.doPost(request,response);
}
}
什么是Session
当人们去医院就诊时,就诊病人需要办理医院的就诊卡,就诊卡上只有卡号,没有其他信息。但病人每次去该医院就诊时,只要出示就诊卡,医务人员便可根据卡号查询到病人的就诊信息。Session技术类似医院办理就诊卡和医院为每个病人保留病历档案的过程。当浏览器访问Web服务器时,Servlet容器就会创建一个Session对象和ID属性, Session对象就相当于病历档案,ID就相当于就诊卡号。当客户端后续访问服务器时,只要将ID传递给服务器,服务器就能判断出该请求是哪个客户端发送的,从而选择与之对应的Session对象为其服务。
Session还具有更高的安全性,它将关键数据保存在服务器。cookie则是将数据存在客户端的浏览器中。因此cookie是较为危险的,若客户端遭遇黑客攻击,cookie信息容易被窃取,数据也可能被篡改,而运用Session可以有效避免这种情况的发生。
HttpSession API
Session是与每个请求消息紧密相关的,为此,HttpServletRequest定义了用于获取Session对象的getSession()方法,该方法有两种重载形式,具体如下:
public HttpSession getSession(boolean create)//第一个
public HttpSession getSession()//第二个
第一个getSession()方法根据传递的参数判断是否创建新的HttpSession对象,如果参数为true,则在相关的HttpSession对象不存在时创建并返回新的HttpSession对象,否则不创建新的HttpSession对象,而是返回null。
HttpSession API
方法声明 | 功能描述 |
---|---|
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**的生命周期**