您的位置:首页 > 其它

会话管理者--Cookie&Session

2017-11-20 15:39 351 查看
在访问网站的时候,肯定不止一个用户,那么对于不同的用户,服务器是如何区分的呢?

Cookie,是一种客户端技术,服务器将每个用户的信息以Cookie的形式保存在用户各自的客户端,之后客户端向服务器发送请求的时候,便携带属于自己的Cookie,那么服务器就能因此处理用户各自的数据

Cookie的使用:

1.从request对象中获取Cookie

Cookie[] cookies = request.getCookies();


2.getName()获得Cookie的属性名

String name = cookies[i].getName();


3.getValue()获得Cookie属性名对应的值

String value = cookies[i].getValue();


4.创建Cookie

Cookie cookie  = new Cookie(name,value);


5.设置Path,即Cookie存储的路径

cookie.setPath(url);
假设URL:http://localhost:8090/Dreams/cookie/ck1
其中应用的根目录是/Dreams
如果不设置Path,那么默认存储的路径是/Dreams/cookie
那么,只有/Dreams/cookie及其子文件目录下的Servlet才能获取到Cookie,如下地址http://localhost:8090/Dreams/ck2是获取不到的;
通常设置的Path为应用的根目录,那么该应用下的所有请求都可以获得Cookie的值。以下三种方式均可以实现该设置
cookie.setPath("/Dreams"); // 不够灵活,如果应用名称改变,则需要手动修改Path的设置
cookie.setPath(request.getPath());
cookie.setPath("/");


6.设置Cookie的有效时间,其中时间是以s为单位

cookie.setMaxAge(time);
如果不设置有效时间,默认的有效时间是会话级别的,即存储在浏览器的内存中,浏览器一旦被关闭,则本次会话结束,Cookie就被删除;若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,此时即使用户关闭了浏览器,在设定的时间之内,Cookie是有效的;将最大时效设为0,则是命令浏览器删除该cookie,注意删除的时候要保证路径一致,否则不会删除;删除后如果会话没有关闭,而且之前设置了存储到硬盘上,那么Cookie也是会存在的。如果为负数,则表示不存储该 cookie。默认的是复数,即不往硬盘上存储Cookie。


7.将Cookie写回客户端

response.addCookie(cookie);


    public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException{
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
//从request对象中获取Cookie
Cookie[] cookies = request.getCookies();for(int i=0;cookies!= null && i<cookies.length;i++){
//getName()获得Cookie的属性名
if("currentTime".equals(cookies[i].getName())){
//getValue()获得Cookie属性名对应的值
long l = Long.parseLong(cookies[i].getValue());
writer.println("上次访问时间:"+new Date(l).toLocaleString());
}
}
//创建Cookie
Cookie cookie = new Cookie("currentTime",System.currentTimeMillis()+"");
//设置Cookie的有效时间
cookie.setMaxAge(60*5);
//设置Cookie的path,以下三种设置方式的结果是一样的,都是将Cookie保存在应用的根目录下,这样根目录下及其子文件夹都能访问到该Cookie
//cookie.setPath("/Dreams");
cookie.setPath("/");
//cookie.setPath(request.getContextPath());
//将Cookie写回客户端
response.addCookie(cookie);}


删除Cookie:

Cookie ck = new Cookie("currentTime","");
ck.setPath("/"); //设置被删除Cookie的Path,否则可能删除失败
//设为0表示删除Cookie
ck.setMaxAge(0);
response.addCookie(ck);


即使是同一个浏览器,不同的会话打开同一个应用,如果不进行Cookie的设置,那么每个会话会建立各自的Cookie,只有将Cookie存入硬盘,且设置路径为当前应用,则同一个应用的两个不同会话才能访问到同一个Cookie

Session,也具有跟Cookie类似的功能,不过最主要的区别在于Session是一种服务器技术,有关每一个用户的信息是保存在服务器Session对象中的。一个浏览器独占一个Session对象

那么问题来了,服务器端为每一个用户建立了一个Session对象保存信息,但是当客户端向服务器发起请求时,Servlet中都是通过request.getSession()方法获得Session对象,对于不同的用户,服务器是如何区分并取出与之相对应的Session对象呢?

这是因为服务器的每个Session对象有一个唯一的SessionID编号,当服务器针对每个用户创建Session对象同时将该Session对象的SessionID写入Cookie传递给浏览器保存在客户端,之后用户向服务器发送请求的时候,浏览器会将Cookie一并发送给服务器,此时服务器通过从Cookie中取SessionID的值,即可找到属于该用户的Session对象。Session是依赖于Cookie技术的。

//获得Session对象
request.getSession();


上述语句获得Session对象的原理:

1. 获取名称为JSESSIONID的Cookie的值

2. 如果没有这样的Cookie,则创建一个新的Session对象,分配唯一的SessionID,并向客户端写一个SessionID=JSESSIONID的Cookie;如果有这样的Cookie,则获取到SessionID的值,从服务器内存中根据获得的ID找到HttpSession对象。

3. 如果找到Session对象,则取出为你服务;如果没有找到,则从步骤2开始

Session对象常用方法:

1. void setAttribute(String name,Object value);

2. Object getAttribute(String name);

3. void removeAttribute(String name);

4. HttpSession.getId():

5. setMaxInactiveInterval(int interval) 设置session的存活时间,以s为单位

6. invalidate() 使此会话无效。通常用户点击退出登录操作时,调用该方法,使得Session无效。

Session的状态:



要想持久化存储,那么存储的对象必须可序列化,即需要实现Serializable接口

我们知道Session是依赖于Cookie的,那么如果客户端禁用Cookie了,那么该怎么办?

解决方式,URL重写,每次请求的URL保存JSESSIONID信息

response. encodeRedirectURL(java.lang.String url)

用于对sendRedirect方法后的url地址进行重写。


response. encodeURL(java.lang.String url)

用于对表单action和超链接的url地址进行重写。
(通过将会话 ID 包含在指定 URL 中对该 URL 进行编码,如果不需要编码,则返回未更改的 URL。此方法的实现包含可以确定会话 ID 是否需要在 URL 中编码的逻辑。例如,如果浏览器支持 cookie,或者关闭了会话跟踪,则 URL 编码就不是必需的。对于健壮的会话跟踪,servlet 发出的所有 URL 都应该通过此方法运行。否则,URL 重写不能用于不支持 cookie 的浏览器)


问题补充:



面试问题:

如果客户端Cookie禁用了,那么Session还能用么?

答案是可用可不用,原本Session的使用依赖于Cookie,那么Cookie被禁用后,那么Session使用Cookie的方式便行不通了, 不过我们可以对URL地址进行重编码,那么JSESSIONID就随着浏览器请求的URL传给服务器,Session依旧是可以使用的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: