Cookie和Session

本文介绍了Cookie和Session在状态管理中的应用。Cookie是保存在客户端的数据,具有大小限制和安全风险,而Session则保存在服务器端,用于跟踪用户状态。当Cookie被禁用时,服务器可通过URL重写传递sessionID。
摘要由CSDN通过智能技术生成

状态管理

  1. 现有问题
  • Http协议是无状态的,不能保存每次提交的信息
  • 如果用户发来一个新的请求,服务器无法知道它是是否与上次的请求联系
  • 对于那些需要提交数据才能完成的web操作,比如登陆来说,就成问题了
  1. 概念
  • 将浏览器与web服务器之间多次交互当作一个整体来处理,并且将多次交互涉及的数据保存下来。
  1. 状态管理分类
  • 客户状态管理技术:将状态保存在客户端,代表性的是Cookie技术
  • 服务器状态管理技术:将状态保存在服务器,代表性的是session技术(服务器传递session时需要使用Cookie的方式)和application

Cookie

  1. 什么是Cookie
  • 是浏览器访问web服务器的某个资源是,由web服务器在HTTP响应消息头中附带传送给浏览器的一小段数据。
  • 一旦web浏览器保存了某个Cookie,那么他以后每次访问改web服务器时,都应在HTTP请求头中将这个Cookie回传给web服务器。
  • 一个Cookie主要有标识该信息的名称(name)和值(value)组成。
    在这里插入图片描述
  1. 创建、发送、获取和修改Cookie
  • 创建和发送cookie
		//服务器端创建Cookie对象
		Cookie cookie = new Cookie("username", "Aim");
		//带中文创建Cookie需要编码
		Cookie cookie2 = new Cookie(URLEncoder.encode("姓名", "UTF-8"), URLEncoder.encode("张三", "UTF-8"));

		//设置Cookie路径
		cookie.setPath("/JavaWebDemo/login");//该路径下的才能获取cookie
		//设置Cookie有效时间
		cookie.setMaxAge(0);//内存存储: >0 有效期,单位秒;=0浏览器关闭;<0内存存储,默认-1

		//响应给客户端
		resp.addCookie(cookie);
  • 在另外一个servlet中获取cookie
		Cookie[] cookies = req.getCookies();
		if(cookies!=null&&cookies.length > 0) {
			for(Cookie cookie : cookies) {
				System.out.println(cookie3.getName()+":"+cookie3.getValue());
				//解码
				System.out.println(URLDecoder.decode(cookie3.getName(), "UTF-8") + ":"+ URLDecoder.decode(cookie3.getValue(), "UTF-8"));
			}
		}
  • 修改cookie就是:只需要保证cookie名和路径一致即可以修改(相当于新建一个cookie,而其值和有效期会覆盖原有的)
  1. 优缺点:
    优点:
    1、可配置到期规则。
    2、简单性:Cookie是一种基于文本的轻量结构,包含简单的键值对。
    3、数据持久性:Cookie默认在过期之前是可以一直存在客户端浏览器上的。
    缺点:
    1、大小受到限制:大多数浏览器对Cookie的大小有4K、8K字节的限制。
    2、用户配置为禁用:有些用户禁用了浏览器或客户端设备接收Cookie的能力,因此限制了这一功能。
    3、潜在的安全风险: Cookie可能会被篡改。会对安全性造成潜在风险或者导致依赖于Cookie的应用程序失败。

Cookie共享问题
       假设在一个 tomcat 服务器中,部署了多个 web 项目,那么在这些web 项目中 cookie 能不能共享?默认情况下 cookie 不能共享,setPath(String path):设置 cookie 的获取范围。默认情况下,设置当前的虚拟目录,如果要共享,则可以将 path 设置为"/"
        不同的 tomcat 服务器间 cookie 共享问题?setDomain(String path):如果设置一级域名相同,那么多个服务器之间 cookie 可以共享。例如:setDomain(".baidu.com"),那么 tieba.baidu.com 和news.baidu.com 中 cookie 可以共享。

例子:
用 Cookie 实现上一次访问时间

package com.gem.demo.servlet;

import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

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

@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("type/html;charset=utf-8");
		Cookie[] cookies = req.getCookies();
		boolean flag = true;
		if (cookies != null && cookies.length > 0) {
			for (Cookie cookie : cookies) {
				String name = cookie.getName();
				if ("lastTime".equals(name)) {
					Date date = new Date();
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
					String str_date = sdf.format(date);
					System.out.println("编码前:" + str_date);
					str_date = URLEncoder.encode(str_date, "UTF-8");
					System.out.println("编码后:" + str_date);
					cookie.setValue(str_date);
					cookie.setMaxAge(60 * 60 * 24 * 30);
					resp.addCookie(cookie);

					String value = cookie.getValue();
					System.out.println("编码前:" + value);
					value = URLDecoder.decode(value, "UTF-8");
					System.out.println("编码后:" + value);
					resp.getWriter().write("<h1>欢迎回来,您上次访问时间为:" + value + "</h1>");
					break;
				}
			}
		}
		if (cookies == null || cookies.length == 0 || flag == false) {
			Date date = new Date();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
			String str_date = sdf.format(date);
			System.out.println("编码前:" + str_date);
			str_date = URLEncoder.encode(str_date, "UTF-8");
			System.out.println("编码后:" + str_date);

			Cookie cookie = new Cookie("lastTime", str_date);
			cookie.setMaxAge(60 * 60 * 24 * 30);
			resp.addCookie(cookie);
			resp.getWriter().write("<h1>您好,欢迎您首次访问</h1>");
		}
	}
}

Session

  1. session概念
  • Session用于记录用户的状态。Session指的是在一段时间内,单个客户端与web服务器的一连串相关的交互过程。
  • 在一个Session中,客户可能会多次请求访问同一个资源,也有可能请求访问各种不同的服务器资源。
  1. session原理
  • 服务器会为每一次会话分配一个Session对象
  • 同一个浏览器发起的多次请求,同属于一次会话(Session)
  • 首次使用到session时,服务器会自动创建Session,并创建Cookie存储Sessionld发送回客户端
  1. session使用
  • Session作用域:拥有存储数据的空间,作用范围是一次会话有效
  • 一次会话是使用同一浏览器发送的多次请求。一旦浏览器关闭,则结束会话
  • 可以将数据存入Session中,在一次会话的任意位置进行获取
  • 可传递任何数据(基本数据类型、对象、集合、数组)
	//获取session对象
	HttpSession session = request.getSession();
	//保存数据
	User user = (User) session.setAttribute("user");
	//移除数据
	session.removeAttribute();
	//获取数据
	User user = (User)session.getAttribute("user");

当客户端关闭后,服务器不关闭,两次获取 session 是否为同一个?默
认情况下。不是。如果需要相同,则可以创建 Cookie,键为 JSESSIONID,设置最大存活时间,让 cookie 持久化保存。

	//获取session
	HttpSession session = request.getSession();
	//创建cookie
	Cookie cookie = new Cookie("JSESSIONID",session.getId());
	cookie.setMaxAge(60*60);
	response.addCookie(cookie);

客户端不关闭,服务器关闭后,两次获取的 session 是同一个吗?不是同
一个,但是要确保数据不丢失。tomcat 自动完成以下工作

        session 的钝化:在服务器正常关闭之前,将 session 对象系列
化到硬盘上
         session 的活化:在服务器启动后,将 session 文件转化为内存
中的 session 对象即可。
session 什么时候被销毁?

  1. 服务器关闭
  2. session 对象调用 invalidate() 。
  3. session 默认失效时间 30 分钟

session、cookie和request区别

  1. session和request
  • request是一次请求有效,请求改变,则request改变
  • session是一次会话有效,浏览器改变,则session改变
  1. session和cookie
  • session 存储数据在服务器端,Cookie 在客户端
  • session 没有数据大小限制,Cookie 有
  • session 数据安全,Cookie 相对于不安全

浏览器被禁止Cookie时,解决方案:

    服务器在默认情况下,会使用Cookie的方式讲sessionID发送给浏览器,如果用户禁止Cookie,则session不会被浏览器保存,此时,服务器可以使用URL重写方式来发送sessionID。

  • URL重写
    浏览器在访问服务器上的某个地址是,不再使用原来的那个地址,而是使用经过改写的地址(即在原来地址后面加上sessionID)
  • 实现URL重写
    response.encodeRedirectURL(url)
	HttpSession session = request.getSession();
	String newUrl = response.encodeRedirectURL(url);
	response.sendRedirect(newUrl);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值