Web之状态管理
第一节 状态管理-Cookie
1.1 状态管理概述
1.1.1 为什么需要状态管理
HTTP协议是无状态的,不能保存每次提交的信息,即当服务器返回与请求相对应的应答之后,这次事务的所有信息就丢掉了。 如果用户发来一个新的请求,服务器无法知道它是否与上次的请求有联系。 对于那些需要多次提交数据才能完成的Web操作,比如登录来说,就成问题了。
1.1.2 什么是状态管理
WEB应用中的会话是指一个客户端浏览器与WEB服务器之间连续发生的一系列请求和响应过程。
WEB应用的会话状态是指WEB服务器与浏览器在会话过程中产生的状态信息,借助会话状态,WEB服务器能够把属于同一会话中的一系列的请求和响应过程关联起来。
1.1.3 状态管理的两种常见模式
客户端状态管理技术:将状态保存在客户端。代表性的是Cookie技术。
服务器状态管理技术:将状态保存在服务器端。代表性的是session技术(服务器传递sessionID时需要使用Cookie的方式)和application
1.2 Cookie应用
1.2.1 什么是Cookie
Cookie是在浏览器访问WEB服务器的某个资源时,由WEB服务器在HTTP响应消息头中附带传送给浏览器的一小段数据,WEB服务器传送给各个客户端浏览器的数据是可以各不相同的。
session由服务器在浏览器第一次请求时创建,发送给浏览器,以后每一次都由浏览器发送给服务器,所有获取session是用request的方法。
一旦WEB浏览器保存了某个Cookie,那么它在以后每次访问该WEB服务器时,都应在HTTP请求头中将这个Cookie回传给WEB服务器。
WEB服务器通过在HTTP响应消息中增加Set-Cookie响应头字段将Cookie信息发送给浏览器,浏览器则通过在HTTP请求消息中增加Cookie请求头字段将Cookie回传给WEB服务器。
一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB
1.2.2 如何创建Cookie
//创建Cookie
Cookie ck=new Cookie("code", code);
ck.setPath("/");//设置Cookie的路径
ck.setMaxAge(-1);//内存存储,取值有三种:>0有效期,单位秒;=0失效;<0内存存储,默认-1
response.addCookie(ck);//让浏览器添加Cookie
//注意:有效路径: 当前访问资源的上一级目录,不带主机名
chrome浏览器查看cookie信息:chrome://settings/content/cookies
1.2.3 如何查询Cookie
//获取所有的Cookie
Cookie[] cks =request.getCookies();
//遍历Cookie
for(Cookie ck:cks){
//检索出自己的Cookie
if(ck.getName().equals("code"))
{
//记录Cookie的值
code=ck.getValue();
break;
}
}
1.2.4 如何修改Cookie
只需要保证Cookie的名和路径一致即可修改
//创建Cookie
Cookie ck=new Cookie("code", code);
ck.setPath("/");//设置Cookie的路径
ck.setMaxAge(-1);//内存存储,取值有三种:>0有效期,单位秒;=0失效;<0内存存储
response.addCookie(ck);//让浏览器添加Cookie
注意:如果改变cookie的name和有效路径会新建cookie,只要name和有效路径相同就会覆盖原有的cookie
1.2.5 Cookie的生存时间
ck.setMaxAge(-1);设置生成时间,默认-1
取值说明:
0有效期,单位秒
=0失效
<0内存存储
1.2.6 Cookie的编码与解码
中文和英文字符不同,中文属于Unicode字符,在内存中占用4个字符,而英文属于ASCII字符,内存中只占2个字节。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会出现乱码。编码可以使用java.net.URLEncoder类的encode(String str,String encoding)方法,解码使用java.net.URLDecoder类的decode(String str,String encoding)方法
代码如下:
保存:Servlet类
// 使用中文的 Cookie. name 与 value 都使用 UTF-8 编码.
Cookie cookie = new Cookie(
URLEncoder.encode("姓名", "UTF-8"),
URLEncoder.encode("老邢", "UTF-8"));
// 发送到客户端
response.addCookie(cookie);
读取:Servlet读取
if(request.getCookies() != null){
for(Cookie cc : request.getCookies()){
String cookieName = URLDecoder.decode(cc.getName(), "UTF-8");
String cookieValue = URLDecoder.decode(cc.getValue(), "UTF-8");
out.println(cookieName + "=");
out.println(cookieValue + "; <br/>");
}
}
else{
out.println("Cookie 已经写入客户端. 请刷新页面. ");
}
1.3 Cookie的路径问题
1.3.1 什么是Cookie的路径问题
cookie 一般都是由于用户访问页面而被创建的,可是并不是只有在创建 cookie 的页面才可以访问这个cookie。在默认情况下,出于安全方面的考虑,只有与创建 cookie 的页面处于同一个目录或在创建cookie页面的子目录下的网页才可以访问。那么此时如果希望其父级或者整个网页都能够使用cookie,就需要进行路径的设置。
cookie.setPath("/");
1.3.2 发送Cookie的条件
浏览器在发送请求之前,首先会根据请求url中的域名在cookie列表中找所有与当前域名一样的cookie,然后再根据指定的路径进行匹配,如果当前请求在域匹配的基础上还与路径匹配那么就会将所有匹配的cookie发送给服务器。
1.3.3 如何设置Cookie的路径
通过Cookie的setPath方法设置路径
1.4 Cookie的特点
优点:
可配置到期规则:Cookie 可以在浏览器会话结束时到期,或者可以在客户端计算机上无限期存在,这取决于客户端的到期规则,不需要任何服务器资源,Cookie 存储在客户端并在发送后由服务器读取。
简单性:Cookie 是一种基于文本的轻量结构,包含简单的键值对。
数据持久性:虽然客户端计算机上 Cookie 的持续时间取决于客户端上的 Cookie 过期处理和用户干预,Cookie 通常是客户端上持续时间最长的数据保留形式
缺点:
大小受到限制:大多数浏览器对 Cookie 的大小有 4096 字节的限制,尽管在当今新的浏览器和客户端设备版本中,支持 8192 字节的 Cookie 大小已愈发常见。
用户配置为禁用:有些用户禁用了浏览器或客户端设备接收 Cookie 的能力,因此限制了这一功能。
潜在的安全风险:Cookie 可能会被篡改。用户可能会操纵其计算机上的 Cookie,这意味着会对安全性造成潜在风险或者导致依赖于Cookie 的应用程序失败。
第二节 状态管理-Session
2.1 Session概述
2.1.1 什么是Session
Session用于跟踪客户的状态。Session指的是在一段时间内,单个客户与Web服务器的一连串相关的交互过程。
在一个Session中,客户可能会多次请求访问同一个网页,也有可能请求访问各种不同的服务器资源。
2.1.2 Session工作原理
不同的网站(服务器)session是不同的,如Session中可能存储的是登录信息,权限信息,所以不同网站的session是不同的。
session被用于表示一个持续的连接状态,在网站访问中一般指代客户端浏览器的进程从开启到结束的过程。session其实就是网站分析的访问(visits)度量,表示一个访问的过程。 session的常见实现形式是cookie(session cookie)(cookie中保存着sessionId),即未设置过期时间的cookie,这个cookie的默认生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。实现机制是当用户发起一个请求的时候,服务器会检查该请求中是否包含sessionid,如果未包含,则系统会创造一个名为JSESSIONID的输出 cookie返回给浏览器(只放入内存,并不存在硬盘中),
并将其以HashTable的形式写到服务器的内存里面;
当已经包含sessionid时,服务端会检查找到与该session相匹配的信息,如果存在则直接使用该sessionid,若不存在则重新生成新的 session。这里需要注意的是session始终是有服务端创建的,并非浏览器自己生成的。
2.1.3 如何获得Session
//获取Session对象
HttpSession session=request.getSession();//
System.out.println("Id:"+session.getId());//唯一标记,
System.out.println("getLastAccessedTime:"+session.getLastAccessedTime());//最后一次访问时间,毫秒
System.out.println("getMaxInactiveInterval:"+session.getMaxInactiveInterval());//获取最大的空闲时间,单位秒
System.out.println("getCreationTime:"+session.getCreationTime());//获取Session的创建,单位毫秒
session.setMaxInactiveInterval(20*60);//设置session的有效时间,单位秒
xml文件设置session有效时间,单位分钟
<session-config>
<!--单位是分钟-->
<session-timeout>10</session-timeout>
</session-config>
2.1.4 如何使用Session绑定对象
使用HttpSession的setAttribute(属性名,Object)方法
session.setAttribute("username", "damon");
在其他servlet中获取session属性的值
//获取session
HttpSession session = request.getSession();
//获取session中的数据
String username = (String)session.getAttribute("username");
System.out.println("username:"+username);
2.1.5 如何删除Session
@WebServlet(name = "InvaliddateSessionServlet"