Cookie/Session

本文详细解析了JavaWeb中的Cookie与Session机制,包括Cookie的用途、使用方法、特性,以及Session的工作原理、作用、创建和销毁时机。通过实际代码示例,展示了如何在JavaWeb中使用Cookie和Session来跟踪用户状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cookie


1. Http协议与Cookie(了解)
  * Cookie是HTTP协议制定的!先由服务器保存Cookie到浏览器再下次浏览器请求服务器时把上一次请求得到Cookie再归还给服务器
  * 由服务器创建保存到客户端浏览器的一个键值对!服务器保存Cookie的响应头:Set-Cookie: aaa=AAA  Set-Cookie: bbb=BBB
    > response.addHeader("Set-Cookie", "aaa=AAA");response.addHeader("Set-Cookie", "bbb=BBB");
  * 当浏览器请求服务器时,会把该服务器保存的Cookie随请求发送给服务器。浏览器归还Cookie的请求头:Cookie: aaa=AAA; bbb=BBB
  * Http协议规定(保证不给浏览器太大压力):
    > 1个Cookie最大4KB
    > 1个服务器最多向1个浏览器保存20个Cookie
    > 1个浏览器最多可以保存300个Cookie
  * 浏览器大战:因为浏览器竞争很激励,所以很多浏览器都会在一定范围内违反HTTP规定,但也不会让一个Cookie为4GB!


2. Cookie的用途
  * 服务器使用Cookie来跟踪客户端状态!
  * 保存购物车(购物车中的商品不能使用request保存,因为它是一个用户向服务器发送的多个请求信息)
  * 显示上次登录名(也是一个用户多个请求)


  **********Cookie是不能跨浏览器的!***********


3. JavaWeb中使用Cookie
  * 原始方式(了解):
    > 使用response发送Set-Cookie响应头
    > 使用request获取Cookie请求头
  * 便捷方式(精通):
    > 使用repsonse.addCookie()方法向浏览器保存Cookie
    > 使用request.getCookies()方法获取浏览器归还的Cookie



  Cookie第一例:
    > 一个jsp保存cookie, a.jsp
    > 另一个jsp获取浏览器归还的cookie! b.jsp


4. Cookie详解
  * Cookie不只有name和value两个属性
  * Cookie的maxAge(掌握):Cookie的最大生命,即Cookie可保存的最大时长。以秒为单位,例如:cookie.setMaxAge(60)表示这个Cookie会被浏览器保存到硬盘上60秒
    > maxAge>0:浏览器会把Cookie保存到客户机硬盘上,有效时长为maxAge的值决定。
    > maxAge<0:Cookie只在浏览器内存中存在,当用户关闭浏览器时,浏览器进程结束,同时Cookie也就死亡了。
    > maxAge=0:浏览器会马上删除这个Cookie!
  * Cookie的path(理解):
    > Cookie的path并不是设置这个Cookie在客户端的保存路径!!!
    > Cookie的path由服务器创建Cookie时设置
    > 当浏览器访问服务器某个路径时,需要归还哪些Cookie给服务器呢?这由Cookie的path决定。
    > 浏览器访问服务器的路径,如果包含某个Cookie的路径,那么就会归还这个Cookie。
    > 例如:
      <> aCookie.path=/day11_1/; bCookie.path=/day11_1/jsps/; cCookie.path=/day11_1/jsps/cookie/;
      <> 访问:/day11_1/index.jsp时,归还:aCookie
      <> 访问:/day11_1/jsps/a.jsp时,归还:aCookie、bCookie
      <> 访问:/day11_1/jsps/cookie/b.jsp时,归还:aCookie、bCookie、cCookie
    > Cookie的path默认值:当前访问路径的父路径。例如在访问/day11_1/jsps/a.jsp时,响应的cookie,那么这个cookie的默认path为/day11_1/jsps/
  * Cookie的domain(了解)
    > domain用来指定Cookie的域名!当多个二级域中共享Cookie时才有用。
    > 例如;www.baidu.com、zhidao.baidu.com、news.baidu.com、tieba.baidu.com之间共享Cookie时可以使用domain
    > 设置domain为:cookie.setDomain(".baidu.com");
    > 设置path为:cookie.setPath("/");




Cookie中不能存在中文!!!


// 保存
Cookie c = new Cookie("username", URLEncoder.encode("张三", "utf-8"));//出错!
response.addCookie(c);


// 获取
Cookie[] cs = request.getCookies();
if(cs != null) {
  for(Cookie c : cs){
    if("username".equals(c.getName())) {
      String username = c.getValue();
      username = URLDecoder.decode(username, "utf-8");
    }
  }
}

显示上次登录时间的COOKIE

<span style="font-size:24px;">package cn.itcast.cookie;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CookieDemo1 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");

		PrintWriter out = response.getWriter();
		out.write("您的上次访问时间是:");

		// 1.得到用户的上次访问时间
		Cookie cookies[] = request.getCookies();
		for (int i = 0; cookies != null && i < cookies.length; i++) {

			Cookie cookie = cookies[i];
			if (cookie.getName().equals("lastAccessTime")) {
				Long time = Long.parseLong(cookie.getValue());

				Date d = new Date(time);
				out.write(d.toLocaleString());
			}
		}

		// 2.给用户以cookie的形式回送最新的时间
		Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+ "");				
		cookie.setMaxAge(10000);
		cookie.setPath("/day18_2");

		response.addCookie(cookie);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}

}
</span>


<span style="font-size:24px;">package cn.itcast.cookie;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LastTimeServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		
		Cookie cookie = new Cookie("lasttime", new Date().toString()); 
		cookie.setMaxAge(60 * 60); 
		response.addCookie(cookie); 
		
		Cookie[] cs = request.getCookies(); 
		String s = "您是首次访问本站!";
		if(cs != null) { 
			for(Cookie c : cs) { 
				if(c.getName().equals("lasttime")) { 
					s = "您上次的访问时间是:" + c.getValue(); 
				}
			}
		}
		
		response.getWriter().print(s); 
	}


	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}

}
</span>


============================================


HttpSession(*****)


1. HttpSession概述
  * HttpSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端!!!
  * HttpSession是Servlet三大域对象之一(request、session、application(ServletContext)),所以它也有setAttribute()、getAttribute()、removeAttribute()方法
  * HttpSession底层依赖Cookie,或是URL重写!


2. HttpSession的作用
  * 会话范围:会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束!
    > 会话:一个用户对服务器的多次连贯性请求!所谓连贯性请求,就是该用户多次请求中间没有关闭浏览器!
  * 服务器会为每个客户端创建一个session对象,session就好比客户在服务器端的账户,它们被服务器保存到一个Map中,这个Map被称之为session缓存!
    > Servlet中得到session对象:HttpSession session = request.getSession();
    > Jsp中得到session对象:session是jsp内置对象之下,不用创建就可以直接使用!
  * session域相关方法:
    > void setAttribute(String name, Object value);
    > Object getAttribute(String name);
    > void removeAttribute(String name);


3. 案例1:演示session中会话的多次请求中共享数据
  * AServlet:向session域中保存数据
  * BServlet:从session域中获取数据
  * 演示:
    > 第一个请求:访问AServlet
    > 第二个请求:访问BServlet


4. 案例2:演示保存用户登录信息(精通)
  * 案例相关页面和Servlet:
    > login.jsp:登录页面
    > succ1.jsp:只有登录成功才能访问的页面
    > succ2.jsp:只有登录成功才能访问的页面
    > LoginServlet:校验用户是否登录成功!
  * 各页面和Servlet内容:
    > login.jsp:提供登录表单,提交表单请求LoginServlet
    > LoginServlet:获取请求参数,校验用户是否登录成功
      <> 失败:保存错误信息到request域,转发到login.jsp(login.jsp显示request域中的错误信息)
      <> 成功:保存用户信息到session域中,重定向到succ1.jsp页面,显示session域中的用户信息
    > succ1.jsp:从session域获取用户信息,如果不存在,显示“您还没有登录”。存在则显示用户信息
    > succ2.jsp:从session域获取用户信息,如果不存在,显示“您还没有登录”。存在则显示用户信息


  只要用户没有关闭浏览器,session就一直存在,那么保存在session中的用户信息也就一起存在!那么用户访问succ1和succ2就会通过!
  
5. HttpSession原理(理解)
  * request.getSession()方法:
    > 获取Cookie中的JSESSIONID:
      <> 如果sessionId不存在,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
      <> 如果sessionId存在,通过sessionId查找session对象,如果没有查找到,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
      <> 如果sessionId存在,通过sessionId查找到了session对象,那么就不会再创建session对象了。
      <> 返回session
    > 如果创建了新的session,浏览器会得到一个包含了sessionId的Cookie,这个Cookie的生命为-1,即只在浏览器内存中存在,如果不关闭浏览器,那么Cookie就一直存在。
    > 下次请求时,再次执行request.getSession()方法时,因为可以通过Cookie中的sessionId找到session对象,所以与上一次请求使用的是同一session对象。
  
  * 服务器不会马上给你创建session,在第一次获取session时,才会创建!request.getSession();


  * request.getSession(false)、request.getSession(true)、request.getSession(),后两个方法效果相同,
    > 第一个方法:如果session缓存中(如果cookie不存在),不存在session,那么返回null,而不会创建session对象。


6. HttpSession其他方法: 
  * String getId():获取sessionId;
  * int getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
  * void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;
  * boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。


7. web.xml中配置session的最大不活动时间
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>


8. URL重写(理解)


  就是把所有的页面中的路径,都使用response.encodeURL("..")处理一下!


  * session依赖Cookie,目的是让客户端发出请求时归还sessionId,这样才能找到对应的session
  * 如果客户端禁用了Cookie,那么就无法得到sessionId,那么session也就无用了!
  * 也可以使用URL重写来替代Cookie
    > 让网站的所有超链接、表单中都添加一个特殊的请求参数,即sessionId
    > 这样服务器可以通过获取请求参数得到sessionId,从而找到session对象。
  * response.encodeURL(String url)

    > 该方法会对url进行智能的重写:当请求中没有归还sessionid这个cookie,那么该方法会重写url,否则不重写!当然url必须是指向本站的url。




1、服务器是如何做到一个session为一个浏览器的多次请求而服务
1.1  服务器创建session出来后,会把 session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再
去访问服务器时,都会带着session 的id号去,服务器发现客户机带session id过来了,就会使用内存中与之对应的
session为之服务

2、如何做到一个session为多个浏览器服务
2.1  服务器第一次创建session,程序员把session id号,手工以cookie的形式回送给浏览器,并设置cookie的有效期
这样,即使用户的浏览器关了,开新浏览器时,还会带着session id找服务器,服务器从而就可以用内存中与之对应的
session为第二个浏览器窗口服务


3、如何做用户禁用cookie后,session还能为多次请求而服务
3.1  把用户可能点的每一个超链接后面,都跟上用户的session id号


4、session对象的创建和销毁时机
4.1 用户第一次request.getSession时
4.2 session对象默认30分钟没有使用,则服务器会自动销毁session,
4.2.1  用户在web.xml文件中手工配置session的失效时间
4.2.2  用户可以手工调用session.invalidate方法,摧毁session

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值