Cookie详解

匿名 (未验证) 提交于 2019-12-03 00:19:01

Cookie简介

Cookie的引文原意是“点心”,它是在客户端访问Web服务器时,服务器在客户端硬盘上存放的信息,好像是服务器发送给客户的“点心”。服务器可以根据Cookie来跟踪客户状态,这对于需要区别客户的场合(如电子商务)特别有用。

当客户端首次请求访问服务器时,服务器先在客户端存放包含该客户的相关信息的Cookie,以后客户端每次请求访问服务器时,都会在HTTP请求数据中包含Cookie,服务器解析HTTP请求中的Cookie,就能由此获得关于客户的相关信息。


Cookie的运行机制是由HTTP协议规定的,多数Web服务器和浏览器都支持Cookie。Web服务器为了支持Cookie,需具备以下功能:

・在HTTP响应结果中添加Cookie数据。

・解析HTTP请求中的Cookie数据。

浏览器为了支持Cookie,需要具备以下功能:

・解析HTTP响应结果中的Cookie数据。

・把Cookie数据保存到本地硬盘。

・读取本地硬盘上的Cookie数据,把它添加到HTTP请求中。

Cookie操作

对Cookie的操作无外乎三部分:读、分析、写。

дCookie

Cookie theCookie = new Cookie(“username” , “Tom”);

response.addCookie(theCookie);

当Servlet向客户端写Cookie时,还可以通过Cookie类的setMaxAge(intexpiry)方法来设置Cookie的有效期。参数expiry以秒为单位,它具有以下含义:

・如果expiry大于零,就指示浏览器在客户端硬盘上保存Cookie的时间为expriy秒。

・如果expiry等于零,就指示浏览器删除当前Cookie。

・如果expiry小于零,就指示浏览器不要把Cookie保存到客户端硬盘。Cookie仅仅存在于当前浏览器进程中,当浏览器进程关闭,Cookie也就消失。

Cookie默认的有效期为-1。对于来自客户端的Cookie,Servlet可以通过Cookie类的getMaxAge()方法来读取Cookie的有效期。

读取分析客户端Cookie

Cookie[] cookies = request.getCookies();

HttpServletRequest类的getCookies()方法返回一个Cookie数组,它包含了HTTP请求中的所有Cookie。如果在HTTP请求中没有任何Cookie,那么getCookies()方法返回null。

对于每个Cookie对象,可调用getName()方法来获得Cookie的名字,调用getValue()方法来获得Cookie的值。

Cookie的使用示例

示例1

先读取客户端的所有Cookie,把每个Cookie的名字、值和有效期打印出来,然后向客户端写一个Cookie。

  1. publicclassextends
  2. privatestaticfinallong
  3. int0
  4. protectedvoidthrows
  5. this
  6. protectedvoidthrows
  7. "text/plain"
  8. ifnull
  9. for(int0
  10. else
  11. new"cookieName""cookieValue"

在web.xml文件中为CookieServlet映射的URL为“/cookie”,按照下面的步骤访问CookieServlet:

示例2 对Cookie的修改和删除

先读取客户端的所有的Cookie,寻找名为username的cookie,然后判断,如果不存在就向客户端写入一个新的Cookie:“username=Tom”,且有效期为1小时;如果存在且值为Tom,将值改为Jack,如果存在且值为Jack,删除该Cookie。

  1. protectedvoidthrows
  2. null
  3. "text/plain"
  4. ifnull
  5. for(int0
  6. if(cookies[i].getName().equals("username"
  7. else
  8. if(cookie==null
  9. new"username""Tom"
  10. 60*60
  11. elseif(cookie.getValue().equals("Tom"
  12. "Jack"
  13. elseif(cookie.getValue().equals("Jack"
  14. 0

Cookie name:username

Cookie value:Tom

Cookie name:username

Cookie value:Jack

假定在Tomcat服务器A上有一个app1应用和一个app2应用,在Tomcat服务器B上有一个app3应用。用户会通过一个浏览器进程访问app1、app2、app3应用。

假定app1应用中的一个Web组件X在浏览器上保存了一个Cookie,当浏览器再次请求访问app1、app2和app3应用中的其他Web组件时,浏览器是否会把Cookie添加到HTTP请求中,从而让这些Web组件能够读取该Cookie呢?

在默认情况下,处于安全的原因,只有app1应用中的Web组件能读取该Cookie。如果希望改变Cookie的共享范围,那么app1应用中的Web组件X在写Cookie时,可以通过setPath(Stringpath)和setDodomain(String domain)方法来设置Cookie的path和domain属性。

Cookie cookie = new Cookie(“username” , “Tom”);

cookie.setPath(“/”);

res.addCookie(cookie);

以上serPath()的参数为“/”,表示Tomcat服务器的根路径,因此同一个Tomcat服务器中的所有Web应用可以共享上述Cookie。

Cookie cookie = new Cookie(“username” , “Tom”);

cookie.setPath(“/app2/”);

res.addCookie(cookie);

以上setPath()的参数为“/app2/”,因此只有Tomcat服务器A中的app2应用可以访问该Cookie,app1应用也无法访问该Cookie。

Cookie cookie = new Cookie(“username” , “Tom”);

cookie.setPath(“/app1/sub”);

res.addCookie(cookie);

www.cat.com。app1应用中的Web组件X的写Cookie的代码:

Cookie cookie = new Cookie(“username” , “Tom”);

cookie.setDomain(“.cat.com”);

res.addCookie(cookie);

模拟taobao等网站的广告推广

类似的网站在客户浏览信息时,会将浏览历史数据保存在客户端,在下次客户打开网站时,向客户推广最近浏览过的商品信息。

页面中的每个连接代表一个商品分类,在点击连接时通过AddCookieServlet向客户端保存Cookie:“itemsNum:6923384801114”:
  1. publicclassextends
  2. privatestaticfinallong
  3. protectedvoidthrows
  4. this
  5. protectedvoidthrows
  6. null
  7. "text/html;charset=utf-8"
  8. "<html><head><title>商品列表</title></head><body><ul><li>"
  9. ifnull
  10. for(int0
  11. if(cookies[i].getName().equals("itemsNum"
  12. "你可能需要:商品编号[""]"
  13. else
  14. "itemNum"
  15. if(itemNum!=null
  16. null?new"itemsNum"
  17. 60*60*24*7
  18. "</body></html>"

打开浏览器访问http://localhost:8080/webdemo/addCookie。初始页面为:

点击其中的一个连接,然后再打开另一个浏览器或是关闭当前网页再打开上面的连接,发现页面会显示上次浏览的商品编号:


此类应用可以根据用户的使用,动态设置推广信息、客户个性化喜好等,还可以在逻辑中增加判断,查看客户隔了多长时间再次访问该网站。

使用Cookie模拟自动登录

用户登录一次后选择自动登录,在下次登录该网站时无需登录步骤,就可直接进入网页。

首先应该有一个过滤器判断用户是否设置了自动登录,如果设置了自动登录则从Cookie中读取数据直接登录,进入网站。创建过滤器,并注册到应用中:

  1. publicclassimplements
  2. publicvoidthrows
  3. publicvoid
  4. publicvoid
  5. throws
  6. if"login.html")&&!req.getRequestURI().endsWith("loginServlet"
  7. "user"
  8. ifnull
  9. ifnull
  10. forint0
  11. if"login"
  12. "&"2
  13. 0
  14. 1
  15. new
  16. "user"
  17. return
  18. "login.html"
  19. return

在该过滤器中先从session中取user值,如果没有则判断该客户端是否有名为login的Cookie,如果有表示该用户设置了自动登录,且已经保存了登录信息(即已经登录过)则直接跳转到目标页面,如果以上条件都没有满足,则跳转至登录页面。web.xml文件中Filter的配置代码为:

  1. <filter>
  2. <filter-name>LoginFilter</filter-name>
  3. <display-name>LoginFilter</display-name>
  4. <filter-class>filter.LoginFilter</filter-class>
  5. </filter>
  6. <filter-mapping>
  7. <filter-name>LoginFilter</filter-name>
  8. <url-pattern>*</url-pattern>
  9. </filter-mapping>

然后创建登录页面:

  1. >
  2. <html>
  3. <head>
  4. <metacharset="UTF-8">
  5. <title>登录</title>
  6. </head>
  7. <body>
  8. <formname"loginForm"method="POST"action="loginServlet">
  9. <table>
  10. <tr>
  11. <td><divalign="right">用户名:</div></td>
  12. <td><inputtype="text"name="username"></td>
  13. </tr>
  14. <tr>
  15. <td><divalign="right">密码:</div></td>
  16. <td><inputtype="password"name="password"></td>
  17. </tr>
  18. <tr>
  19. <td><inputtype="checkbox"name="autoLogin">自动登录</td>
  20. </tr>
  21. <tr>
  22. <td><inputtype="submit"name="submit"value="登录"></td>
  23. <td><inputtype="reset"name="reset"value="重置"></td>
  24. </tr>
  25. </table>
  26. </form>
  27. </body>
  28. </html>
该登录页面请求Servlet,在Servlet中进行数据的校验等工作:
  1. publicclassextends
  2. privatestaticfinallong
  3. protectedvoidthrows
  4. this
  5. protectedvoidthrows
  6. boolean"autoLogin")!=null&&req.getParameter("autoLogin").equals("on")?true:false
  7. "username"
  8. "password"
  9. new
  10. "user"
  11. null
  12. ifnull
  13. for(int0
  14. if(cookies[i].getName().equals("login"
  15. "&"
  16. ifnull
  17. new"login""&"
  18. if
  19. 60*60*24*7
  20. else
  21. 0
  22. "hello.jsp"
在该Servlet中完成的工作是将用户信息保存至session并根据逻辑判断操作Cookie。登录成功后页面跳转至欢迎页面hello.jsp:

  1. <language="java"contentType=
  2. pageEncoding="utf-8"import="helloworld.bean.User"%>
  3. http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <metahttp-equiv="Content-Type"content=>
  7. <title>hello</title>
  8. <user>
  9. </head>
  10. <body>
  11. <b>你好:<></b>
  12. </body>
  13. </html>

在保存用户信息时使用到一个简单的JavaBean:User。

以上就是该实验中用到的页面。按照以下步骤进行访问:

http://localhost:8080/webdemo/hello.jsp,发现会被拦截到登录页面,输入登录信息,此时不勾选自动登录,点击登录,页面跳转至hello.jsp。

http://localhost:8080/webdemo/hello.jsp,被拦截到登录页面。此时填写登录信息后勾选自动登录,登录成功后关闭浏览器。

http://localhost:8080/webdemo/hello.jsp,此时发现没有被拦截,原因是上一步中向客户端写了一个Cookie,打开浏览器并访问时,程序读取到用户信息直接放入session,完成了自动登录的功能。

访问http://localhost:8080/webdemo/login.html.。此时不勾选自动登录,登录成功后,重复步骤一、二,自动登陆功能已经取消。

Cookie简介

Cookie的引文原意是“点心”,它是在客户端访问Web服务器时,服务器在客户端硬盘上存放的信息,好像是服务器发送给客户的“点心”。服务器可以根据Cookie来跟踪客户状态,这对于需要区别客户的场合(如电子商务)特别有用。

当客户端首次请求访问服务器时,服务器先在客户端存放包含该客户的相关信息的Cookie,以后客户端每次请求访问服务器时,都会在HTTP请求数据中包含Cookie,服务器解析HTTP请求中的Cookie,就能由此获得关于客户的相关信息。


Cookie的运行机制是由HTTP协议规定的,多数Web服务器和浏览器都支持Cookie。Web服务器为了支持Cookie,需具备以下功能:

・在HTTP响应结果中添加Cookie数据。

・解析HTTP请求中的Cookie数据。

浏览器为了支持Cookie,需要具备以下功能:

・解析HTTP响应结果中的Cookie数据。

・把Cookie数据保存到本地硬盘。

・读取本地硬盘上的Cookie数据,把它添加到HTTP请求中。

Cookie操作

对Cookie的操作无外乎三部分:读、分析、写。

дCookie

Cookie theCookie = new Cookie(“username” , “Tom”);

response.addCookie(theCookie);

当Servlet向客户端写Cookie时,还可以通过Cookie类的setMaxAge(intexpiry)方法来设置Cookie的有效期。参数expiry以秒为单位,它具有以下含义:

・如果expiry大于零,就指示浏览器在客户端硬盘上保存Cookie的时间为expriy秒。

・如果expiry等于零,就指示浏览器删除当前Cookie。

・如果expiry小于零,就指示浏览器不要把Cookie保存到客户端硬盘。Cookie仅仅存在于当前浏览器进程中,当浏览器进程关闭,Cookie也就消失。

Cookie默认的有效期为-1。对于来自客户端的Cookie,Servlet可以通过Cookie类的getMaxAge()方法来读取Cookie的有效期。

读取分析客户端Cookie

Cookie[] cookies = request.getCookies();

HttpServletRequest类的getCookies()方法返回一个Cookie数组,它包含了HTTP请求中的所有Cookie。如果在HTTP请求中没有任何Cookie,那么getCookies()方法返回null。

对于每个Cookie对象,可调用getName()方法来获得Cookie的名字,调用getValue()方法来获得Cookie的值。

Cookie的使用示例

示例1

先读取客户端的所有Cookie,把每个Cookie的名字、值和有效期打印出来,然后向客户端写一个Cookie。

  1. publicclassextends
  2. privatestaticfinallong
  3. int0
  4. protectedvoidthrows
  5. this
  6. protectedvoidthrows
  7. "text/plain"
  8. ifnull
  9. for(int0
  10. else
  11. new"cookieName""cookieValue"

在web.xml文件中为CookieServlet映射的URL为“/cookie”,按照下面的步骤访问CookieServlet:

示例2 对Cookie的修改和删除

先读取客户端的所有的Cookie,寻找名为username的cookie,然后判断,如果不存在就向客户端写入一个新的Cookie:“username=Tom”,且有效期为1小时;如果存在且值为Tom,将值改为Jack,如果存在且值为Jack,删除该Cookie。

  1. protectedvoidthrows
  2. null
  3. "text/plain"
  4. ifnull
  5. for(int0
  6. if(cookies[i].getName().equals("username"
  7. else
  8. if(cookie==null
  9. new"username""Tom"
  10. 60*60
  11. elseif(cookie.getValue().equals("Tom"
  12. "Jack"
  13. elseif(cookie.getValue().equals("Jack"
  14. 0

Cookie name:username

Cookie value:Tom

Cookie name:username

Cookie value:Jack

假定在Tomcat服务器A上有一个app1应用和一个app2应用,在Tomcat服务器B上有一个app3应用。用户会通过一个浏览器进程访问app1、app2、app3应用。

假定app1应用中的一个Web组件X在浏览器上保存了一个Cookie,当浏览器再次请求访问app1、app2和app3应用中的其他Web组件时,浏览器是否会把Cookie添加到HTTP请求中,从而让这些Web组件能够读取该Cookie呢?

在默认情况下,处于安全的原因,只有app1应用中的Web组件能读取该Cookie。如果希望改变Cookie的共享范围,那么app1应用中的Web组件X在写Cookie时,可以通过setPath(Stringpath)和setDodomain(String domain)方法来设置Cookie的path和domain属性。

Cookie cookie = new Cookie(“username” , “Tom”);

cookie.setPath(“/”);

res.addCookie(cookie);

以上serPath()的参数为“/”,表示Tomcat服务器的根路径,因此同一个Tomcat服务器中的所有Web应用可以共享上述Cookie。

Cookie cookie = new Cookie(“username” , “Tom”);

cookie.setPath(“/app2/”);

res.addCookie(cookie);

以上setPath()的参数为“/app2/”,因此只有Tomcat服务器A中的app2应用可以访问该Cookie,app1应用也无法访问该Cookie。

Cookie cookie = new Cookie(“username” , “Tom”);

cookie.setPath(“/app1/sub”);

res.addCookie(cookie);

www.cat.com。app1应用中的Web组件X的写Cookie的代码:

Cookie cookie = new Cookie(“username” , “Tom”);

cookie.setDomain(“.cat.com”);

res.addCookie(cookie);

模拟taobao等网站的广告推广

类似的网站在客户浏览信息时,会将浏览历史数据保存在客户端,在下次客户打开网站时,向客户推广最近浏览过的商品信息。

页面中的每个连接代表一个商品分类,在点击连接时通过AddCookieServlet向客户端保存Cookie:“itemsNum:6923384801114”:
  1. publicclassextends
  2. privatestaticfinallong
  3. protectedvoidthrows
  4. this
  5. protectedvoidthrows
  6. null
  7. "text/html;charset=utf-8"
  8. "<html><head><title>商品列表</title></head><body><ul><li>"
  9. ifnull
  10. for(int0
  11. if(cookies[i].getName().equals("itemsNum"
  12. "你可能需要:商品编号[""]"
  13. else
  14. "itemNum"
  15. if(itemNum!=null
  16. null?new"itemsNum"
  17. 60*60*24*7
  18. "</body></html>"

打开浏览器访问http://localhost:8080/webdemo/addCookie。初始页面为:

点击其中的一个连接,然后再打开另一个浏览器或是关闭当前网页再打开上面的连接,发现页面会显示上次浏览的商品编号:


此类应用可以根据用户的使用,动态设置推广信息、客户个性化喜好等,还可以在逻辑中增加判断,查看客户隔了多长时间再次访问该网站。

使用Cookie模拟自动登录

用户登录一次后选择自动登录,在下次登录该网站时无需登录步骤,就可直接进入网页。

首先应该有一个过滤器判断用户是否设置了自动登录,如果设置了自动登录则从Cookie中读取数据直接登录,进入网站。创建过滤器,并注册到应用中:

  1. publicclassimplements
  2. publicvoidthrows
  3. publicvoid
  4. publicvoid
  5. throws
  6. if"login.html")&&!req.getRequestURI().endsWith("loginServlet"
  7. "user"
  8. ifnull
  9. ifnull
  10. forint0
  11. if"login"
  12. "&"2
  13. 0
  14. 1
  15. new
  16. "user"
  17. return
  18. "login.html"
  19. return

在该过滤器中先从session中取user值,如果没有则判断该客户端是否有名为login的Cookie,如果有表示该用户设置了自动登录,且已经保存了登录信息(即已经登录过)则直接跳转到目标页面,如果以上条件都没有满足,则跳转至登录页面。web.xml文件中Filter的配置代码为:

  1. <filter>
  2. <filter-name>LoginFilter</filter-name>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!