SERVLETJSP学习(六)—— 状态管理-cookie

1. 状态管理-Cookie

1.1. 状态管理

1.1.1. 为什么需要状态管理

Web应用程序使用HTTP协议作为传输数据的标准协议,而HTTP协议是无状态协议,即一次请求对应一次响应,响应结束后连接即断开,同一个用户的不同请求对于服务器端来讲并不会认为这两个请求有什么关联性,并不会以此区分不同的客户端。但实际情况中还是需要服务器端能够区分不同的客户端以及记录与客户端相关的一些数据,所以状态管理能够做到不同客户端的身份识别。

1.1.2. 什么是状态管理

将客户端与服务器之间多次交互当做一个整体来看待,并且将多次交互中涉及的数据保存下来,提供给后续的交互进行数据的管理即状态管理。

这里的状态指的是当前的数据,管理指的是在这个多次交互的过程中对数据的存储、修改、删除。

生活中很多与状态管理类似的案例。如洗车卡记录洗车次数就是很典型的状态管理。洗车卡可以是一张记录简单次数的标示,车主每次携带卡片洗车后由商家修改,车主即可带走这张记录数据的卡片,商家不会保存任何数据,客户自己负责携带需要维护的数据。还有一种处理方式就是商家只给客户一个卡号,每次客户来洗车时自己不会记录洗车次数,只要报上卡号,商家就会从系统中找到与卡号对应的数据,修改后仍然是商家保存,客户带走的只是一个卡号这个标示。

以上两种模式都能实现洗车次数的记录,也就是数据的管理,只是各有利弊,程序中的状态管理与这个案例都采用了同样的处理原理。

1.1.3. 状态管理两种常见模式

状态管理的过程中重要的是数据的保存,只有存下来的数据才能在多次交互中起到记录的作用,所以可以按照管理的数据的存储方式和位置的不同来区分状态管理的模式。

如果将数据存储在客户端,每次向服务器端发请求时都将存在客户端的数据随着请求发送到服务器端,修改后再发回到客户端保存的这种模式叫做Cookie。

如果将数据存储在服务器端,并且为这组数据标示一个编号,只将编号发回给客户端。当客户端向服务器发送请求时只需要将这个编号发过来,服务器端按照这个编号找到对应的数据进行管理的这种模式叫做Session——会话。

1.2. Cookie

1.2.1. 什么是Cookie

一小段文本信息随着请求和响应,在客户端和服务器端之间来回传递。根据设定的时间来决定该段文本在客户端保存时长的这种工作模式叫做Cookie。最初服务器将信息发给客户端时是通过响应数据的Set-Cookie头信息来完成的。

1.2.2. Cookie的原理

如图-1所示为Cookie的生成及使用原理。

图 - 1

如果客户端向服务器端AddServlet发送请求,遇到创建Cookie的代码时,那么一小段文本信息就会随着response响应中的头信息被传递会客户端。如图中Set-Cookie:uname=xxx就是从服务器端传递回客户端的文本信息。当文本信息到达客户端以后,会被保存在客户端的内存或硬盘上,存在内存中会随着内存的释放而消失,存在硬盘上则会保存更长的时间。

一旦客户端存有服务器发回的文本信息,那么当浏览器再次向服务器发起请求时,如请求FindServlet这个组件,那么存储的文本信息会随着请求数据包的消息头以Cookie:uname=xxx这样的形式将文本信息发送到服务器端。只要Cookie的生命周期没有结束,那么不管是存在内存还是硬盘上的信息都会在客户端向服务器端发出请求时自动的随着消息头发送过去。

1.2.3. 如何创建Cookie

Servlet API提供了javax.servlet.http.Cookie这种类型来解释Cookie。其中存储的文本以name-value对的形式进行区分,所以创建Cookie时指定name-value对即可。这个name-value最终是以Set-Cookie这种消息头的形式跟随相应数据包到达客户端,所以要想将数据添加到消息头中需要使用response对象提供的方法。

创建Cookie的代码如下所示:

  1. Cookie c = new Cookie(String name,String value);
  2. response.addCookie( c );

代码中的第一行实现了这段name-value对的文本的创建。

代码中的第二行执行的效果就是在响应数据包中追加一个Set-Cookie的消息头。如果发送了相同name的Cookie数据,那么之前的数据会被覆盖。能够创建多少个Cookie存放在客户端与当前浏览器的种类相关。

以下代码实现了创建两个Cookie:

  1. import java.io.IOException;
  2. import java.io.PrintWriter;
  3. import java.net.URLEncoder;
  4. import javax.servlet.*;
  5. import javax.servlet.*;
  6. public class AddCookieServlet extends HttpServlet {
  7. public void service(HttpServletRequest request,
  8. HttpServletResponse response)
  9. throws ServletException, IOException {
  10. response.setContentType(
  11. "text/html;charset=utf-8");
  12. PrintWriter out = response.getWriter();
  13. //创建cookie
  14. Cookie c = new Cookie("username","Lisa");
  15. Cookie c2 = new Cookie("city","NewYork");
  16. response.addCookie(c);
  17. response.addCookie(c2);
  18. out.close();
  19. }
  20. }

1.2.4. 如何查询Cookie

当客户端向服务器发出请求时,服务器端可以尝试着从请求数据包的消息头中获取是否携带了Cookie信息。实现这一功能的代码如下:

  1. Cookie[] request.getCookies();

由于客户端是可以存放多个Cookie的,所以request提供的获取Cookie的方法的返回值是Cookie数组,如果想进一步获取某一个Cookie信息可以通过遍历数组,分别获取每一个Cookie的name和value。代码如下:

  1. Cookie[] cookies = request.getCookies();
  2. if(cookies!=null){
  3. for(Cookie c : cookies){
  4. String cookieName = c.getName();
  5. String cookieValue = c.getValue();
  6. }
  7. }

查询Cookie的完整代码如下:

  1. import java.io.IOException;
  2. import java.io.PrintWriter;
  3. import java.net.URLDecoder;
  4. import javax.servlet.*;
  5. import javax.servlet.http.*;
  6. public class FindCookieServlet extends HttpServlet {
  7. public void service(HttpServletRequest request,
  8. HttpServletResponse response)
  9. throws ServletException, IOException {
  10. response.setContentType("text/html;charset=utf-8");
  11. PrintWriter out = response.getWriter();
  12. Cookie[] cookies = request.getCookies();
  13. if(cookies != null){
  14. for(int i=0;i<cookies.length;i++){
  15. Cookie c = cookies[i];
  16. String name = c.getName();
  17. String value = c.getValue();
  18. out.println(name + ":" value + "<br/>");
  19. }
  20. }else{
  21. out.println("没有找到cookie");
  22. }
  23. out.close();
  24. }
  25. }

1.2.5. 如何修改Cookie

所谓Cookie的修改,本质是获取到要变更值的Cookie,通过setValue方法将新的数据存入到cookie中,然后由response响应对象发回到客户端,对原有旧值覆盖后即实现了修改。主要实现代码:

  1. Cookie[] cookies = request.getCookies();
  2. if(cookies!=null){
  3. for(Cookie c : cookies){
  4. String cookieName = c.getName();
  5. if(name.equals(“uname”)){
  6. c.setValue(“Mark”);
  7. response.addCookie( c );
  8. }
  9. }

其中response.addCookie(c)是非常重要的语句,如果没有这一行代码,那么就算是使用setValue方法修改了Cookie的值,但是不发回到客户端的话,也不会实现数值的改变。所以只要见到response.addCookie这行代码,即服务器端发回了带有Set-Cookie消息头的信息。

1.2.6. Cookie的生存时间

默认情况下,Cookie会被浏览器保存在内存中,此时Cookie的生命周期由浏览器决定,只要不关闭浏览器Cookie就会一直存在。

如果希望关闭浏览器后Cookie仍存在,则可以通过设置过期时间使得Cookie存在硬盘上得以保存更长的时间。

设置Cookie的过期时间使用如下代码:

  1. void setMaxAge(int seconds);

该方法是Cookie提供的实例方法。参数seconds的单位为秒,但精度不是很高。

seconds > 0 :代表Cookie保存在硬盘上的时长

seconds = 0 : 代表Cookie的生命时长为现在,而这一刻稍纵即逝,所以马上Cookie就等同于过了生存时间,所以会被立即删除。这也是删除Cookie的实现方式。

seconds < 0 :缺省值,浏览器会将Cookie保存在内存中。

以下代码实现了Cookie保存在硬盘上40秒:

  1. import java.io.IOException;
  2. import java.io.PrintWriter;
  3. import java.net.URLEncoder;
  4. import javax.servlet.*;
  5. import javax.servlet.*;
  6. public class AddCookieServlet extends HttpServlet {
  7. public void service(HttpServletRequest request,
  8. HttpServletResponse response)
  9. throws ServletException, IOException {
  10. response.setContentType(
  11. "text/html;charset=utf-8");
  12. PrintWriter out = response.getWriter();
  13. //创建cookie
  14. Cookie c = new Cookie("username","Lisa");
  15. c.setMagAge(40);
  16. Cookie c2 = new Cookie("city","NewYork");
  17. response.addCookie(c);
  18. response.addCookie(c2);
  19. out.close();
  20. }
  21. }

1.2.7. Cookie编码

Cookie作为在网络传输的一段字符串文本,只能保存合法的ASCII字符,如果要保存中文需要将中文变成合法的ASCII字符,即编码。使用如下代码可以实现将中文保存到Cookie中。

  1. Cookie c = new Cookie("city",URLEncoder.encode("北京","utf-8"));

完整实现保存用户名和城市信息的代码如下。

  1. import java.io.IOException;
  2. import java.io.PrintWriter;
  3. import java.net.URLEncoder;
  4. import javax.servlet.*;
  5. import javax.servlet.*;
  6. public class AddCookieServlet extends HttpServlet {
  7. public void service(HttpServletRequest request,
  8. HttpServletResponse response)
  9. throws ServletException, IOException {
  10. response.setContentType(
  11. "text/html;charset=utf-8");
  12. PrintWriter out = response.getWriter();
  13. //创建cookie
  14. Cookie c = new Cookie("username",URLEncoder.encode("女神",”utf-8”));         Cookie c2 = new Cookie("city",URLEncoder.encode(“北京”."utf-8"));
  15. response.addCookie(c);
  16. response.addCookie(c2);
  17. out.close();
  18. }
  19. }

1.2.8. Cookie解码

服务器读取客户端经过编码之后的信息时,要想能够正确显示需要将信息解码后才能输出。使用URLDecoder的decode()方法即可。实现解码的完整代码如下:

  1. import java.io.IOException;
  2. import java.io.PrintWriter;
  3. import java.net.URLDecoder;
  4. import javax.servlet.*;
  5. import javax.servlet.*;
  6. public class FindCookieServlet extends HttpServlet {
  7. public void service(HttpServletRequest request,
  8. HttpServletResponse response)
  9. throws ServletException, IOException {
  10. response.setContentType("text/html;charset=utf-8");
  11. PrintWriter out = response.getWriter();
  12. Cookie[] cookies = request.getCookies();
  13. if(cookies != null){
  14. for(int i=0;i<cookies.length;i++){
  15. Cookie c = cookies[i];
  16. String name = c.getName();
  17. String value = c.getValue();
  18. out.println(name + “:” + URLDecoder.decode(value,"utf-8"));
  19. }
  20. }else{
  21. out.println("没有找到cookie");
  22. }
  23. out.close();
  24. }
  25. }

1.3. Cookie的路径问题

1.3.1. 什么是Cookie的路径问题

客户端存储Cookie之后,并不是针对同一个应用访问任何资源时都自动发送Cookie到服务器端,而是会进行路径的判断。只有符合路径规范的请求才会发送Cookie到服务器端。

客户端在接受Cookie时会为该Cookie记录一个默认路径,这个路径记录的是添加这个Cookie的Web组件的路径。如,当客户端向 http://localhost:8080/test/file/addCookie.jsp发送请求时创建了cookie,那么该cookie的路径就是 /test/file.

1.3.2. 什么时候发送Cookie

只有当访问的地址是Cookie的路径或者其子路径时,浏览器才发送Cookie到服务器端。

如,Cookie的路径是 /test/file,那么如果访问的是 /test/file/a.jsp 或者 /test/file/b/c.jsp时,都会发送Cookie。

如果访问的是 /test/d.jsp,则浏览器不会发送Cookie。

1.3.3. 如何设置Cookie的路径

设置Cookie的路径可以使用Cookie的API方法,setPath(String uri);

如以下代码就实现了设置Cookie的路径为应用的顶级目录,这样所有资源路径要么与此路径相等,要么是子路径,从而实现了客户端发送任何请求时都会发送Cookie。

  1. Cookie c = new Cookie(“uname”,“jack”);
  2. c.setPath(“/test”);
  3. response.addCookie(c);

1.3.4. Cookie的限制

Cookie由于存放的位置在客户端,所以可以通过修改设置被用户禁止。Cookie本质就是一小段文本,一小段说的是只能保存少量数据,长度是有限制的,一般为4kb左右。文本说的是只能保存字符串,不能保留复杂的对象类型数据。

作为网络中传输的内容,Cookie安全性很低,非常容易通过截取数据包来获取,在没有加密的情况下不要用于存放敏感数据。

就算是能够存放的长度很短,但作为网络中传输的内容也会增加网络的传输量影响带宽。在服务器处理大量请求的时候,Cookie的传递无疑会增加网络的负载量。

时间: 2024-08-24 11:31:28

SERVLETJSP学习(六)—— 状态管理-cookie的相关文章

2014-07-09 Java Web的学习(5)-----会话管理(Cookie和Session)

1.什么是会话 会话,牛津词典对其的解释是进行某活动连续的一段时间.从不同的层面看待会话,它有着类似但不全然相同的含义.比如,在web应用的用户看来,他打开浏览器访问一个电子商务网站,登录.并完成购物直到关闭浏览器,这是一个会话.而在web应用的开发者开来,用户登录时我需要创建一个数据结构以存储用户的登录信息,这个结构也叫做会话.因此在谈论会话的时候要注意上下文环境.而本文谈论的是一种基于HTTP协议的用以增强web应用能力的机制或者说一种方案,它不是单指某种特定的动态页面技术,而这种能力就是保

状态管理cookie和session

是由php提供的,session开关要放在代码最前面,session是保存在服务器的一般保存20分钟,cookie是保存在客户端的随便给值. 状态管理cookie和session,布布扣,bubuko.com

[原创]java WEB学习笔记28: 会话与状态管理Cookie 机制

1.会话与状态管理 1)背景 ① HTTP协议是一种无状态的协议,WEB服务器本身不能识别出哪些请求是同一个浏览器发出的 ,浏览器的每一次请求都是完全孤立的: ② 作为 web 服务器,必须能够采用一种机制来唯一地标识一个用户,同时记录该用户的状态: ③ 问题:怎么才能实现网上商店中的购物车呢:某个用户从网站的登录页面登入后,再进入购物页面购物时,负责处理购物请求的服务器程序必须知道处理上一次请求的程序所得到的用户信息. 2)会话和会话状态 ① WEB应用中的会话:指一个客户端浏览器与WEB服务

状态管理cookie 案例

1状态管理:服务器为了追踪同一个客户端发出的请求,将多次交互看成一个整体看待 2:cookie的生存时间,默认情况下,cookie保存在浏览器内存中,只要不关闭浏览器,cookie就一直存在 如果希望关闭浏览器后,cookie仍然存在,可以设置过期时间 3:在写cookie是,为了让浏览器访问到同一应用的cookie,最好设置cookie的默认路径 c.setPath(/day07); 4.1 增加Cookie代码: //创建cookie Cookie c1 = new Cookie("unam

状态管理-Cookie

1.为什么需要状态管理 Web应用程序使用HTTP协议通信,而HTTP协议是“无状态”协议,即服务器一旦响应完客户的请求之后,就断开连接,而同一个客户的下一次请求将重新建立网络连接 服务器应用程序有时是需要判断是否为同一客户发出的请求,比如客户的多次选购商品.因此,有必要跟踪同一客户发出的一系列请求. 2.什么是状态管理 将客户端(浏览器)与服务器之间多次交互(一次请求,一次响应)当做一个整体来看待,并且将多次交互所涉及的数据即状态保存下来 状态指的是数据 管理指的是多次交互时对数据的修改 3.

git学习 六 分支管理

分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN. 如果两个平行宇宙互不干扰,那对现在的你也没啥影响.不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN! 分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了.如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险. 现在有了分支,就不用怕了.你

aspx页面状态管理Cookie和ViewState

Cookie 设置cookie protected void Button2_Click(object sender, EventArgs e) { HttpCookie cookie = new HttpCookie("user"); cookie.Value = "这是cookie"; cookie["sex"] = "女"; cookie.Values.Add("age", "18"

JSP | 基础 | JSP状态管理 | Cookie &amp;&amp; Session

Cookie : 是web服务器保存在客户端的一系列文本信息. Cookie的作用: 1.对特定的对象的追踪 2. 3. JSP中创建Cookie以及使用 创建Cookie对象 写入Cookie对象 使用Cookie对象 Cookie在登录应用: 需求: 用户在勾选记住密码后, 1. 保存用户密码24小时,并在另外一个页面上显示通过cookie读取用户的用户名和密码, 2. 在返回登录页面上,自动填充用户名以及密码 注意: 1. 用户名可以为中文字符,需要解决中文字符转码问题 2. 原文地址:h

状态管理之cookie使用及其限制、session会话

# 1.什么是状态管理? 将浏览器与web服务器之间多次交互当作一个整体来处理,并且将多次交互所涉及的数据(即状态)保存下来.(cookie浏览器所涉及到的访问数据保存下来)# 2.如何进行状态管理? 方式一 将状态保存在浏览器端(Cookie). 方式二 将状态保存在服务器端(Session). # 3.Cookie## (1)什么是Cookie? 服务器临时存放在浏览器端的少量数据. ## (2)工作原理 当浏览器访问服务器时,服务器将少量数据以set-cookie消息头的形式发送给浏览器,