12、会话管理
程序员文章站
2022-07-12 14:48:42
...
一、什么是会话?
- 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
- 会话过程中要解决的一些问题?
- ----每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。
- ----例如:用户点击超链接通过一个servlet购买了一个商品,程序应该想办法保存用户购买的商品,以便于用户点结帐servlet时,结帐servlet可以得到用户购买的商品为用户结帐。
- ----保存在request或servletContext中是肯定不行的
二、保存会话数据的两种技术
- Cookie
- Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
- Session
- Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务
三、API
- javax.servlet.http.Cookie类用于创建一个Cookie,response接口中也定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie
/** * javax.servlet.http.Cookie * 创建一个 cookie,cookie 是 servlet 发送到 Web 浏览器的少量信息,这些信息由浏览器保存,然后发送回服务器。 * cookie 的值可以唯一地标识客户端,因此 cookie 常用于会话管理。 * 一个 cookie 拥有一个名称、一个值和一些可选属性,比如注释、路径和域限定符、最大生存时间和版本号。 * 一些 Web 浏览器在处理可选属性方面存在 bug,因此有节制地使用这些属性可提高 servlet 的互操作性。 * servlet 通过使用 HttpServletResponse#addCookie 方法将 cookie 发送到浏览器,该方法将字段添加到 HTTP 响应头,以便一次一个地将 cookie 发送到浏览器。 * 浏览器应该支持每台 Web 服务器有 20 个 cookie,总共有 300 个 cookie,并且可能将每个 cookie 的大小限定为 4 KB。 * 浏览器通过向 HTTP 请求头添加字段将 cookie 返回给 servlet。 * 可使用 HttpServletRequest#getCookies 方法从请求中获取 cookie。一些 cookie 可能有相同的名称,但却有不同的路径属性。 * 浏览器通过向 HTTP 请求头添加字段将 cookie 返回给 servlet。可使用 HttpServletRequest#getCookies 方法从请求中获取 cookie。一些 cookie 可能有相同的名称,但却有不同的路径属性。 * 此类支持版本 0(遵守 Netscape 协议)和版本 1(遵守 RFC 2109 协议)cookie 规范。默认情况下,cookie 是使用版本 0 创建的,以确保最佳互操作性。 */ public class Cookie{ //构造方法 public Cookie(String name, String value){} //常用方法 String getComment() {}//获取注释信息 String getDomain() {} int getMaxAge() {} String getName() {}//没有setName的方法 String getPath() {} boolean getSecure() {} String getValue() {} int getVersion() {} // ------------------------------------------- void setComment(String purpose) {} void setDomain(String pattern) {} void setMaxAge(int expiry) {} void setPath(String uri) {} void setSecure(boolean flag) {} void setValue(String newValue) {} void setVersion(int v) {} }
public Cookie(String name,String value) setValue与getValue方法 setMaxAge与getMaxAge方法 ,单位是秒,如果不指定此属性则保存在浏览器内存中,如果设置了,则保存在浏览器缓存文件夹中,如果设置为0,则浏览器会删除同名cookie setPath与getPath方法,控制浏览器什么时候带着此Cookie来访问,比如设置为/Day05则访问/Day05及其子路径时会带着cookie,如果没有设置path则,比如访问/Day05/servlet/Demo则默认为/servlet setDomain与getDomain方法 .google.com 所有浏览器都拒绝接受第三方cookie,所以此方法基本上无用 getName方法 ,没有setName方法
/** * javax.servlet.http.HttpSession * 提供一种方式,跨多个页面请求或对 Web 站点的多次访问标识用户并存储有关该用户的信息。 * servlet 容器使用此接口创建 HTTP 客户端和 HTTP 服务器之间的会话。 * 会话将保留指定的时间段,跨多个连接或来自用户的页面请求。 * 一个会话通常对应于一个用户,该用户可能多次访问一个站点。服务器能够以多种方式维护会话,比如使用 cookie 或重写 URL。 * servlet 应该能够处理客户端选择不加入会话的情况,比如故意关闭 cookie 时。 */ public interface HttpSession{ Object getAttribute(String name); void setAttribute(String name, Object value); void removeAttribute(String name); Enumeration getAttributeNames(); long getCreationTime();//创建时间 String getId(); long getLastAccessedTime(); int getMaxInactiveInterval();//得到最大不活跃间隔 void setMaxInactiveInterval(int interval); ServletContext getServletContext(); void invalidate();//让此Session作废 }
四、Cookie应用
- 显示用户上次访问时间,每次访问的时候将当前时间设置为cookie发给浏览器
- 显示用户上次浏览过的商品
- Cookie不接受中文,如果输入中文则设置不成功,不过可以进行URL编码,读取的时候进行解码就ok了
-
String value = URLEncoder.encode("中文", "utf-8"); cookie.setValue(value);//url编码并设置 String value = c.getValue(); value = URLDecoder.decode(date, “utf-8”);//url解码
- 注意,如果浏览器没有带Cookie过来则getCookies方法返回会是个null,要进行非空判断
五、Cookie细节
- 一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)
- 一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
- 浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
- 如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
- 注意,删除cookie时,path必须一致,否则不会删除(浏览器通过cookie的name+path来标识一个cookie)
六、session概述
- 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
- session是一个域对象,作用范围为整个会话。
- Session和Cookie的主要区别在于:Cookie是把用户的数据写给用户的浏览器。Session技术把用户的数据写到用户独占的session中。
- session的生命周期
- Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象,如果服务器发现内存中没有该浏览器对应的session就会创建该session并返回,如果已经存在则直接返回已有的session。
- session并不会一直存在在内存中,经过一段时间如果无人使用session将会被销毁,一般这个时间为30分钟,可以在web.xml中配置<session-config>设置该时间值
- 调用session的invalidate()也可以销毁session
- 使用Session完成简单的购物功能
七、session实现原理
- 服务器是如何实现一个session为一个用户浏览器服务的?
- 如何实现多个IE浏览器共享同一session?(应用:关掉IE后,再开IE,上次购买的商品还在。)
- 多个IE浏览器共享同一session
- 在简单购物案例中,由于一个浏览器对应一个Session,所以当我们重新开一个浏览器时,是无法找到在上一个浏览器中购买的商品的,这在电子商务中是无法接受的,其实我们可以利用session的原理巧妙的使同一台机器内的多个浏览器共用一个session
- 由于服务器识别浏览器是通过Jsessionid这个特殊的cookie进行的,我们可以手动设置该cookie的setMaxAge,使这个cookie被保存在硬盘中被多个浏览器公用,从而使同一台机器上的多个浏览器公用一个session。(注意设置cookie值时path也要相同)。
八、IE禁用Cookie后的session处理
- 注意:即使禁止了Cookie,浏览器对localhost是不阻止的,要想试验就要用127.0.0.1进行
- ie6对localhost开头的不起作用,ie8是可以起作用的
- 解决方案:URL重写
-
response. encodeRedirectURL(java.lang.String url) 用于对sendRedirect方法后的url地址进行重写。 response. encodeURL(java.lang.String url) 用于对表单action和超链接的url地址进行重写
九、session案例
- 使用Session完成用户登陆(注销、*注册)
- 利用Session防止表单重复提交
- 方式一:利用javascript
<script type="text/javascript"> var isCommited = false; function checkPost(){ if(!isCommited){ isCommited = true; return true; }else{ alert("不能重复提交"); return false; } } </script>
- 缺点:当用户单击”刷新”,或单击”后退”再次提交表单,将导致表单重复提交
- 方式二:
- 表单页面由servlet程序生成,servlet为每次产生的表单页面分配一个唯一的随机标识号,并在FORM表单的一个隐藏字段中设置这个标识号,同时在当前用户的Session域中保存这个标识号。
- 当用户提交FORM表单时,负责处理表单提交的serlvet得到表单提交的标识号,并与session中存储的标识号比较,如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。
- 在下列情况下,服务器程序将拒绝用户提交的表单请求:
- ----存储Session域中的表单标识号与表单提交的标识号不同
- ----当前用户的Session中不存在表单标识号
- ----用户提交的表单数据中没有标识号字段
十、ServeltContext 、reqeust、session域的比较
- servletContext 的作用域是整个web应用,随着服务器启动而创建,如果应用被移除出主机或服务器关闭则销毁。
- request 的作用域是整个请求链,每一次请求都会创建一个request,当请求结束时request销毁。
- session 的作用于是整个会话,第一次调用reqeust.getSession时创建,当一段时间没有使用或服务器关闭或调用session.invalidate方法时销毁
- 什么时候用ServeltContext什么时候用reqeust什么时候用session?
- ----如果一个数据只是用来显示的话就用request域
- 如果一个数据除了用来显示以外我一会还要用,这时候用session
- 如果一个数据除了用来显示以外还要给别人用,这时候用ServletContext域
上一篇: 数学基础--线性代数
下一篇: 30.标准模板库 STL 简介