会话跟踪技术(一):Session和Cookie技术

来源:互联网 发布:mac单机游戏迅雷下载 编辑:程序博客网 时间:2024/06/05 09:13

写在前面的话,cookie和session的定义:
        当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择,都纪录下来。当下次你再光临同一个网站,WEB 服务器会先看看有没有它上次留下的 Cookie 资料,有的话,就会依据 Cookie里的内容来判断使用者,送出特定的网页内容给你。 Cookie 的使用很普遍,许多有提供个人化服务的网站,都是利用 Cookie来辨认使用者,以方便送出使用者量身定做的内容,像是 Web 接口的免费 email 网站,都要用到 Cookie。
具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。


一.什么是会话技术:

会话可以理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应。例如你给10086打个电话,你就是客户端,而10086服务人员就是服务器了。从双方接通电话那一刻起,会话就开始了,到某一方挂断电话表示会话结束。在通话过程中,你会向10086发出多个请求,那么这多个请求都在一个会话中。
JavaWeb中,客户向某一服务器发出第一个请求开始,会话就开始了,直到客户关闭了浏览器会话结束。
        在一个会话的多个请求中共享数据,这就是会话跟踪技术。例如在一个会话中的请求如下:
        (1) 请求银行主页;
        (2) 请求登录(请求参数是用户名和密码);
        (3) 请求转账(请求参数与转账相关的数据);
        (4) 请求信誉卡还款(请求参数与还款相关的数据)。
        在这上面的会话中当前用户信息必须在这个会话中共享的,因为登录的是张三,那么在转账和还款时一定是相对张三的转账和还款!这就说明我们必须在一个会话过程中有共享数据的能力。


二.Cookie技术

HTTP协议是无状态协议,也就是说每个请求都是独立的!无法记录前一次请求的状态;但HTTP协议中可以使用Cookie来完成会话跟踪!在JavaWeb中,使用session来完成会话跟踪,session底层依赖Cookie技术。

1.Cookie概述

1.1什么叫Cookie

Cookie翻译成中文是小甜点,小饼干的意思。是由服务器创建,然后通过响应发送给客户端的一个键值对,在HTTP中它表示服务器送给客户端浏览器的小甜点。客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie)。当客户端下一次服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器,这样服务器就可以识别客户端了!

1.2Cookie规范:

  • Cookie大小上限为4KB;
  • 一个服务器最多在客户端浏览器上保存20个Cookie;
  • 一个浏览器最多保存300个Cookie;
          当然上面的数据只是HTTP的Cookie规范,但在浏览器大战的今天,一些浏览器为了打败对手,为了展现自己的能力起见,可能对Cookie规范“扩展”了一些,例如每个Cookie的大小为8KB,最多可保存500个Cookie等!但也不会出现把你硬盘占满的可能!
          注意,不同浏览器之间是不共享Cookie的。也就是说在你使用IE访问服务器时,服务器会把Cookie发给IE,然后由IE保存起来,当你在使用FireFox访问服务器时,不可能把IE保存的Cookie发送给服务器。

1.3Cookie与HTTP头:

Cookie是通过HTTP请求和响应头在客户端和服务器端传递的:
(1)Cookie:请求头**客户端发送给服务器端;
      格式:Cookie: a=A; b=B; c=C。即多个Cookie用分号离开;
(2) Set-Cookie:响应头,服务器端发送给客户端;
      一个Cookie对象一个Set-Cookie:
      Set-Cookie: a=A
      Set-Cookie: b=B
      Set-Cookie: c=C

1.4Cookie的覆盖

      如果服务器端发送重复的Cookie那么会覆盖原有的Cookie,例如客户端的第一个请求服务器端发送的Cookie是:Set-Cookie: a=A;第二请求服务器端发送的是:Set-Cookie: a=AA,那么客户端只留下一个Cookie,即:a=AA。

1.5Cookie的第一个例子:

客户端访问AServlet,AServlet在响应中添加Cookie,浏览器会自动保存Cookie。然后客户端访问BServlet,这时浏览器会自动在请求中带上Cookie,BServlet获取请求中的Cookie打印出来。

这里写图片描述

AServlet.java如下:

 public class AServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        String id = UUID.randomUUID().toString();//生成一个随机字符串        Cookie cookie = new Cookie("id", id);//创建Cookie对象,指定名字和值        response.addCookie(cookie);//在响应中添加Cookie对象        response.getWriter().print("已经给你发送了ID");    }    }

BServlet.java如下:

public class BServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)        throws ServletException, IOException {    response.setContentType("text/html;charset=utf-8");    Cookie[] cs = request.getCookies();//获取请求中的Cookie    if(cs != null) {//如果请求中存在Cookie        for(Cookie c : cs) {//遍历所有Cookie            if(c.getName().equals("id")) {//获取Cookie名字,如果Cookie名字是id                response.getWriter().print("您的ID是:" + c.getValue());//打印Cookie值            }        }    }}

2.Cookie的生命

什么是Cookie的生命:
      所谓生命就是Cookie在客户端的有效时间,可以通过setMaxAge(int)来设置Cookie的有效时间。
(1)cookie.setMaxAge(-1):cookie的maxAge属性的默认值就是-1,表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么cookie就会消失。
(2)cookie.setMaxAge(60*60):表示cookie对象可存活1小时。当生命大于0时,浏览器会把Cookie保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie也会存活1小时;
(3)cookie.setMaxAge(0):cookie生命等于0是一个特殊的值,它表示cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie。

3.Cookie的path

3.1什么是Cookie的路径

现在有WEB应用A,向客户端发送了10个Cookie,这就说明客户端无论访问应用A的哪个Servlet都会把这10个Cookie包含在请求中!但是也许只有AServlet需要读取请求中的Cookie,而其他Servlet根本就不会获取请求中的Cookie。这说明客户端浏览器有时发送这些Cookie是多余的!
可以通过设置Cookie的path来指定浏览器,在访问什么样的路径时,包含什么样的Cookie。

3.2Cookie路径与请求路径的关系

我们来看看Cookie路径的作用:
下面是客户端浏览器保存的3个Cookie的路径:
a: /cookietest;
b: /cookietest/servlet;
c: /cookietest/jsp;

下面是浏览器请求的URL:
A: http://localhost:8080/cookietest/AServlet;
B: http://localhost:8080/cookietest/servlet/BServlet;
C: http://localhost:8080/cookietest/jsp/CServlet;

  • 请求A时,会在请求中包含a;
  • 请求B时,会在请求中包含a、b;
  • 请求C时,会在请求中包含a、c;

也就是说,请求路径如果包含了Cookie路径,那么会在请求中包含这个Cookie,否则不会在请求中包含这个Cookie。

  • A请求的URL包含了“/cookietest”,所以会在请求中包含路径为“/cookietest”的Cookie;
  • B请求的URL包含了“/cookietest”,以及“/cookietest/servlet”,所以请求中包含路径为“/cookietest”和“/cookietest/servlet”两个Cookie;
  • C请求的URL包含了“/cookietest”,以及“/cookietest/jsp”,所以请求中包含路径为“/cookietest”和“/cookietest/jsp”两个Cookie;

3.3设置Cookie的路径

设置Cookie的路径需要使用setPath()方法,例如:
cookie.setPath(“/cookietest/servlet”);
如果没有设置Cookie的路径,那么Cookie路径的默认值当前访问资源所在路径,例如:
* 访问http://localhost:8080/cookietest/AServlet时添加的Cookie默认路径为/cookietest;
* 访问http://localhost:8080/cookietest/servlet/BServlet时添加的Cookie默认路径为/cookietest/servlet;
* 访问http://localhost:8080/cookietest/jsp/BServlet时添加的Cookie默认路径为/cookietest/jsp;

4.Cookie中保存中文

Cookie的name和value都不能使用中文,如果希望在Cookie中使用中文,那么需要先对中文进行URL编码,然后把编码后的字符串放到Cookie中。
* 向客户端响应中添加Cookie:

    String name = URLEncoder.encode("姓名", "UTF-8");    String value = URLEncoder.encode("张三", "UTF-8");    Cookie c = new Cookie(name, value);    c.setMaxAge(3600);    response.addCookie(c);

* 从客户端请求中获取Cookie:
Cookie[] cs = request.getCookies();
if(cs != null) {
for(Cookie c : cs) {
String name = URLDecoder.decode(c.getName(), "utf-8");
String value = URLDecoder.decode(c.getValue(), "utf-8");
System.out.println(name + "=" + value);
}
}

三.Session技术:

1.session的实现原理

      当我首次去银行时,因为还没有账号,所以需要开一个账号,我获得的是银行卡,而银行这边的数据库中留下了我的账号(Session),我的钱是保存在银行的账号中,而我带走的是我的卡号(sessionId)。
当我再次去银行时,只需要带上我的卡,而无需再次开一个账号了。只要带上我的卡,那么我在银行操作的一定是我的账号!
      当首次使用session时,服务器端要创建session,session是保存在服务器端,而给客户端的session的id(一个cookie中保存了sessionId)。客户端带走的是sessionId,而数据是保存在session中。
当客户端再次访问服务器时,在请求中会带上sessionId,而服务器会通过sessionId找到对应的session,而无需再创建新的session。

这里写图片描述

2.session与浏览器

      session保存在服务器,而sessionId通过Cookie发送给客户端,但这个Cookie的生命不-1,即只在浏览器内存中存在,也就是说如果用户关闭了浏览器,那么这个Cookie就丢失了。
当用户再次打开浏览器访问服务器时,就不会有sessionId发送给服务器,那么服务器会认为你没有session,所以服务器会创建一个session,并在响应中把sessionId中到Cookie中发送给客户端。
      你可能会说,那原来的session对象会怎样?当一个session长时间没人使用的话,服务器会把session删除了!这个时长在Tomcat中配置是30分钟,可以在${CATALANA}/conf/web.xml找到这个配置,当然你也可以在自己的web.xml中覆盖这个配置!
<session-config>
<session-timeout>30</session-timeout>
</session-config>

      session失效时间也说明一个问题!如果你打开网站的一个页面开始长时间不动,超出了30分钟后,再去点击链接或提交表单时你会发现,你的session已经丢失了!

3.session其他常用API

  • String getId():获取sessionId;
  • int getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
  • void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;
  • long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;
  • long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;
  • void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;
  • boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。

4.URL重写

      我们知道session依赖Cookie,那么session为什么依赖Cookie呢?因为服务器需要在每次请求中获取sessionId,然后找到客户端的session对象。那么如果客户端浏览器关闭了Cookie呢?那么session是不是就会不存在了呢?
      其实还有一种方法让服务器收到的每个请求中都带有sessioinId,那就是URL重写!在每个页面中的每个链接和表单中都添加名为jSessionId的参数,值为当前sessionid。当用户点击链接或提交表单时也服务器可以通过获取jSessionId这个参数来得到客户端的sessionId,找到sessoin对象。

在index.jsp中配置:

<body><h1>URL重写</h1>    <a href='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' >主页</a>    <form action='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' method="post">    <input type="submit" value="提交"/></form></body>

也可以使用response.encodeURL()对每个请求的URL处理,这个方法会自动追加jsessionid参数,与上面我们手动添加是一样的效果。

<a href='<%=response.encodeURL("/day06_5/index.jsp") %>' >主页</a><form action='<%=response.encodeURL("/day06_5/index.jsp") %>' method="post">    <input type="submit" value="提交"/></form>

使用response.encodeURL()更加“智能”,它会判断客户端浏览器是否禁用了Cookie,如果禁用了,那么这个方法在URL后面追加jsessionid,否则不会追加。

四.cookie 和session 的区别:

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、所以个人建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中

原创粉丝点击