概述
- 问题引入
- HTTP协议是一种无状态的协议。WEB服务器本身不能识别出哪些请求是同一个浏览器发出的且每次请求是完全孤立的
- HTTP1.1支持持续连接,但当用户有一段时间没提出请求,连接也会关闭
- 因此作为WEB服务器,必须能够采用一种机制来唯一地识别一个用户,同时记录该用户的状态
- 会话
- 浏览器与服务器之间连续发生的一系列请求与响应过程
- 会话状态
- 浏览器与服务器之间在会话过程中产生的状态信息,借助会话状态,可把一系列请求与响应过程关联起来
- 会话ID
- WEB服务器能识别出同一个浏览器的访问请求,需浏览器对其发出每个请求都进行识别,属于同一个会话的请求带同样的标识号,标识号称之为会话ID
- 完成会话跟踪机制:Cookie,Session
Cookie
- 在浏览器访问WEB服务器的某个资源时,由WEB服务器在HTTP响应信息头中附带传送给浏览器的一个小文本文件(Cookie)
- 一旦浏览器保存了某个Cookie,以后每次访问WEB服务器时都在HTTP请求头中将Cookie回传给WEB服务器
- 一个Cookie只能识别一种信息,至少包含一个识别该信息的名称和设置值
- WEB服务器可给浏览器发送多个Cookie,浏览器也可接受多个服务器提供的Cookie
- 浏览器一般只允许存放300个Cookie,web站点最多存放20个Cookie,每个Cookie大小限制为4KB
方法
- Servlet API中提供一个Cookie类来封装Cookie信息,包含生成和提起Cookie信息各个属性的方法
- public Cookie(String name,String value) //创建
- String geyName() //获取Cookie的名称
- String getValue() //获取Cookie的值
- int getMaxAge() //获取cookie的过期时间,以秒为单位
- String getPath(String uri) //获取Cookie的使用路径
- String getDomain() //获取Cookie适用的域
- void setValue(String value) //在Cookie创建后,为Cookie赋予新的值
- void setMaxAge(int expiry) //设置Cookie的过期时间,以秒为单位
- void setPath(String uri) //设置Cookie的使用路径
- void setDomain(String pattern) //设置访问Cookie的域名
- HttpServletResponse接口
- response.addCookie(Cookie cookie) //将一个Cookie对象传入客户端,将Cookie插入到一个Set-Cookie HTTP响应头中,而非修改响应头
- HttpServletRequest接口
- Cookie[] cookies = request.getCookies() //读取所有Cookie项
- 支持中文
- URLEncoder.encode(数据,“utf-8”) //对数据编码
- URLDecoder.decode(数据,“utf-8”) //对数据解码
会话Cookie
- 不设置过期时间,则Cookie的声明周期为浏览器会话期间,关闭浏览器则Cookie消失,会话Cookie一般不保存在硬盘上而保存在内存中
持久Cookie
- 设置过期时间,浏览器则把Cookie保存在硬盘上,关闭浏览器Cookie不消失,可在不同浏览器进程间共享,比如两个IE窗口,而保存在内存中的Cookie,不同浏览器处理方式不同
Session
- 相比于Cookie,Session是服务器端使用的一种记录客户端状态的机制,Cookie保存在客户端浏览器中,而Session保存在服务器上
- 在web开发过程中,服务器给每个用户浏览器会创建一个会话对象(session对象),一个浏览器独享一个session对象,因此在保存用户数据时,服务器程序可以把用户数据写到用户浏览器独享的session中。当用户使用浏览器访问其他程序时,其他程序可以从用户的session中取出该用户的数据,直接使用
- session的实现是依赖于cookie的。服务器创建Session之后,会把session的ID,以cookie的形式回写给客户端(一个cookie中保存了sessionId),name属性为JSESSIONID,而数据是保存在session中,只要不关闭客户端,包含sessionId的cookie会一直保存到浏览器中,即这次会话中的所有访问该服务器的请求头中都会带上sessionId,而服务器会通过sessionId找到对应的session,而无需再创建新的session
方法
- HttpSession接口
- void setAttribute(String name, Object value) //设置session中的数据,若多次调用该方法且使用相同的name,那么会覆盖上一次的值
- Object getAttribute(String name) //获取session中的数据
- void removeAttribute(String name) //移除session中的数据
- invalidate() //销毁session,session默认失效时间:30分钟,服务器关闭,session销毁(Cookie销毁)
- setMaxInactiveInterval(s) //设置session失效时间,s以秒为单位
- getMaxInactiveInterval() //获取session失效时间
- 在web.xml中设置session失效时间
- <session-config>
- <session-timeout>失效时间</session-timeout>
- </session-config>
- <session-config>
- HttpServletRequest接口
- getSession()或getSession(true) //获取与创建session对象
- getSession(false) //禁用session
URL地址重写
- URL地址重写是对客户端不支持Cookie的解决方案,URL地址重写的原理是将该用户Session的id信息重写到URL地址中,服务器能够解析重写后的URL获取Session的id, HttpServletResponse类提供了encodeURL(String url)实现URL地址重写
- encodeURL方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中
- response.encodeRedirectURL(String url) 用于对sendRedirect方法后的url地址进行重写
区别
- Cookie保存在客户端,未设置存储时间的Cookie,关闭浏览器会话Cookie就会被删除;设置了存储时间的Cookie保存在用户设备的磁盘中直到过期,同时Cookie在客户端可以伪造,不是十分安全,敏感数据不易保存。Session保存在服务器端,存储在IIS的进程开辟的内存中,而Session过多会消耗服务器资源,所以尽量少使用Session
- Session技术把用户的数据写到用户独占的session中,通过SessionID用户能够与服务器端成千上万的Session进行匹配,同时也保证了不同页面之间传值的正确性
- 存储数据类型不同:Session能够存储任意的Java对象,Cookie只能存储String类型的对象
- 大于10K的数据,不能使用Cookies