状态管理
为什么需要状态管理
· Web应用程序使用HTTP协议通信,而HTTP协议是“无状态”协议,即服务器一旦响应完客户的请求之后,就断开连接,而同一个客户的下一次请求将重新建立连接;
· 服务器应用程序有时需要判断是否为同一个客户发出的请求,比如客户多次选购商品。因此,有必要跟踪同一个客户发出的一系列请求;
什么是状态管理
· 将客户端(浏览器)与服务器之间多次交互(一次请求,一次响应)当做一个整体来看待,并且将多次交互所涉及的数据即状态保存下来
· 状态指的是数据
· 管理指的是多次交互时对数据的修改
状态管理的两种常见模式
· 客户端状态管理技术:将状态保存在客户端。代表性的是Cookie技术;
· 服务器状态管理技术:将状态保存在服务端。代表性的是Session技术;
Cookie
什么是Cookie
· 浏览器向Web服务器发送请求时,服务器会将少量的数据以set-Cookie消息头的方式发给浏览器,浏览器将这些数据保存下来;当浏览器再次访问服务器的时候,会将这些数据以Cookie消息头的方式发送给服务器;
Cookie的原理
如何创建Cookie
· Servlet API为使用Cookie提供了javac.servlet.http.Cookie;
· 创建:
//name:用于区分不同Cookie的名字 //value:Cookie的值 Cookie c = new Cookie(String name,String value); response.addCookie(c)
如何查询Cookie
· 获取客户端所有的Cookie对象:
Cookie[]request.getCookies();
注:该方法有可能返回null;
· 获取一个Cookie对象的名称或值:
String Cookie.getName(); String Cookie.getValue()
如何修改Cookie
· step1,获取客户端发送的所有Cookie;
· step2,根据name找到要修改的Cookie;
· step3,调用Cookie的setValue(String newValue)方法修改该Cookie的值;
· step4,将修改后的Cookie加入到response发送给客户端;
代码:Cookie[] cookies = request.getCookies(); if(cookies!=null){ for(Cookie c:cookies){ String name = c.getName(); if(name.equals("city")){ c.setValue("Shanghai"); //同名Cookie会覆盖,以达到修改的目的 response.addCookie(c); } } }
Cookie的生存时间
· 默认情况下,浏览器会将Cookie保存在内存中,只要浏览器不关闭,Cookie就会一直存在;
· 如果希望关闭浏览器后Cookie仍在,可以通过设置过期时间;
//seconds单位是秒,精度不是很高 void Cookie.setMaxAge(int seconds)
· seconds>0:浏览器要保存Cookie的最长时间为设置的参数值,如果超过指定的时间,浏览器会删除这个Cookie。此Cookie保存在硬盘上;
· seconds=0:删除Cookie;在修改Cookie的生存时间为0后,随着response发送回客户端,替换原有的Cookie,因生命周期到了即将该Cookie删除;
· seconds<0:缺省值,浏览器会将Cooie保存到内存中;
Cookie编码
· Cookie只能保存合法的ASCIIZIFU ;如果要保存中文,需要将中文装换为合法的ASCII字符,即编码;
Cookie c = new Cookie( "city",URLEncoder.encode("北京","utf-8") );
Cookie解码
· 解码后的Cookie为了看到实际的中文,需要还原后在显示;
Cookie[]Cookies = request.getCookies(); if(Cookies!=null){ Cookie c = new Cookie[0]; String value = c.getValue(); //与编码时格式保持一致 value = URLDecoder.decode(value,"utf-8"); }
Cookie的路径问题
什么是Cookie的路径
· 浏览器在访问服务器上的某个地址时,会比较Cookie的路径与该路径是否匹配,只有匹配的Cookie才会发送给服务器;
· Cookie的默认路径等于添加这个Cookie的Web组件的路径;
· 如:/appName/file/addCookie.jsp添加一个Cookie,则该Cookie的路径等于/appName/file
发送Cookie的条件
· 要访问的地址必须是Cookie的路径或者其子路径,浏览器才会发送Cookie;
· 如:
- Cookie的路径是/appName/file
- 则访问/appName/file/a.jsp 或 /appName/file/b.jsp 时会发送Cookie;
- 如果访问/appName/c.jsp 则不会发送Cookie;
如何设置Cookie路径
· 使用如下代码段可以设置Cookie的路径
Cookie c = new Cookie("uname","jack"); c.setPath("/appName"); response.addCookie(c);
Cookie的限制
· Cookie可以被用户禁止;
· Cookie会将状态保存在浏览器端,不安全;对于敏感数据,需要加密后再使用Cookie来保存;
· Cookie只能保存少量数据,大约4KB;
· Cookie的个数是有限制的;
· Cookie只能保存字符串;
Session
什么是session
· 浏览器访问Web服务器时,服务器会为每一个浏览器在服务端的内存中分配空间,单独创建一个Session对象,该对象有一个Id属性,其值唯一,一般称之为SessionId,并且服务器会将这个SessionId(使用Cookie的方式)发送给浏览器;浏览器再次访问的服务器时,会将sessionId发送给服务器,服务器可以依据SessionId找到对应的Session对象;
Session工作原理
如何获得Session
方式一:
HttpSession s = request.getSession(boolean flag);
· HttpSession是一个接口,后面返回的是符合接口规范的对象;
· 当flag为true时:先查看请求中有没有SessionId,如果没有SessionId,服务器会创建一个Session对象;如果有SessionId, 依据SessionId查找对应的Session对象,找到则返回;找不到则创建一个新的Session对象,所以flag为true时,一定能得到一 个Session对象;
· 当flag为false时,没有SessionId及有SessionId但没有找到Session对象,均返回null;找到则返回;
方式二:
HttpSession s = request.getSession();
· 等价于request.getSession(true);
· 提供该方法是为了代码书写更方便一些,大部分情况下是不管找没找到都需要返回一个Session对象;
如何使用Session绑定对象
· 绑定对象:
void Session.setAttribute(String name,Object obj);
· 获取绑定对象:
Object Session.getAttribute(String name);
· 移除绑定对象:
Void Session.removeAttribute(String name);
注:getAttribute方法的返回值是Object类型,在去除数据时要对其进行数据类型转换,且必须与我们存入的数据类型一致;
· 立即删除Seeson对象:
Session.invalidate()
Seesion验证
· 用户访问需要保护的资源时,可以使用Session验证的方式来保证其安全性,比如要求登录后才能访问的资源;
· 实现Session验证,遵循以下步骤:
- 1、使用Session.setAttribute()先绑定数据;
- 2、使用Session.getAttribute()方式来读取绑定值,如果没有,则跳转到登录页面;
Session超时
什么是session超时
· Web服务器会将空闲时间过长的Session对象删除掉,以节省服务器内存空间资源;
· Web服务器缺省的超时时间限制:一般是30分钟;
如何修改Session的缺省时间限制
方式一:
· 通过修改tomcat中 conf/web.xml 文件的设置
<session-config> <session-timeout>30</session-timeout> </session-config>
方式二:
void session.setMaxInactiveInterval(int seconds);
浏览器禁用Cookie的后果
· 如果浏览器禁用Cookie,Session就不能用了;但是可以通过其他的方式解决;
· 服务器在默认情况下,会使用Cookie的方式将SessionId发送给浏览器,如果用户禁用了Cookie,则SessionId不会被浏览器保存,此时,服务器可以使用如:URL重写这样的方式来发送SessionId;
URL重写
什么是URL重写
· 浏览器在访问服务器上的某个地址时,不再使用原来的那个地址,而是使用经过修改的地址(即,在原来的地址上加上SessionId);
如何实现URL重写
· 如果是连接地址和表单提交,使用response.encodeURL(String url) 生成重写后的URL;
· 如果是重定向,使用response.encodeRedirectURL(String url) 生成重写后的URL;
Session的优缺点
· 优点
- 安全(将状态保存在服务器端);
- Session能够保存的数据类型更丰富,Cookie只能保存字符串;
- Session能够保存更多的数据,Cookie大约只有4KB;
· 缺点
- Session将状态保存在服务器端,占用服务器内存,如果用户量过大,会严重影响服务器性能;
Session和Cookie的区别
(1)Session是保存在服务器端,客户无法知道其中的信息,安全性更高;而Cookie是保存在客户端,服务端可以知晓其中的信息;
(2)Session保存的是对象,而Cookie只能保存字符串;
(3)Session不区分路径,同一个用户在同一个网站期间,所有的Session在任何一个地方都是通用的,而Cookie是区分路径的,如果设置了路径参数,那么同一个网站不同路径下的Cookie是互相访问不到的;
(4)Session可以保存更多数据,而Cookie只能保存大约4KB;