Cookie与Session

Cookie

什么是Cookie

​ 浏览器向服务器发送请求,服务器会将少量的数据以set-cookie消息头的方式发送给浏览器,浏览器会将其保存下来,但浏览器再次向服务器发送请求时,会将数据以cookie消息头的方式发送给服务器,在服务端可以从请求数据包获取cookie的信息,通过此方式,可以实现状态管理的目的。

在这里插入图片描述

保存到哪?

一般保存到用户本地的appData目录下

Cookie是否有上限

  • 一个cookie只能保存一个信息:key-value
  • 一个web占点可以给浏览器多个cookie,最多存放20个cookie
  • Cookie大小限制在4KB
  • 浏览器cookie上线300左右

添加、获取

//创建cookie	name:cookie名称 value:cookie值
Cookie cookie = new Cookie(String name,String value);
cookie.setMaxAge(24*60*60); //设置cookie的有效期
resp.addCookie(cookie); //响应给客户端一个cookie

//获得Cookie
Cookie[] cookies = req.getCookies(); 
cookie.getName(); //获得cookie中的key
cookie.getValue(); //获得cookie中的vlaue

编码解码

Java语言内存中,使用Unicode编码格式保存字符(中文、英文占2个字节)

  • 编码:把Unicode编码格式所对应的字节数组转成某种本地编码格式(utf-8)所对应的字节数组
  • 解码:把某种本地编码格式(utf-8)所对应的字节数组转成Unicode编码格式所对应的字节数组
//默认情况下,cookie只能存储ascii字符串,如果需要存储中文,必须编码
URLEncoder.encode("数据","utf-8")	//编码
URLDecoder.decode(cookie.getValue(),"UTF-8")  //解码

删除Cookie

  1. 不设置有效期,关闭浏览器自动删除

  2. 设置有效期为0

    //默认情况下,cookie的数据保存在内存中,当打开浏览器时,操作系统会为该进程分配一块内存空间,
    //cookie的数据保存在里面,当浏览器关闭,进程消失,对应的内存空间被释放,相应的cookie数据消失。
    //可以通过cookie.setMaxAge(int seconds);改变保存时间,单位:秒
        
    seconds>0:cookie的数据保存在硬盘中,当超过指定的时间,cookie数据被删除
    seconds<0:默认情况,cookie数据保存在内存中,只要浏览器不关闭,数据就一直存在
    seconds=0:立即删除cookie数据
    

保存时间

默认情况下,cookie的数据保存在内存中,当打开浏览器时,操作系统会为该进程分配一块内存空间,
cookie的数据保存在里面,当浏览器关闭,进程消失,对应的内存空间被释放,相应的cookie数据消失。
可以通过cookie.setMaxAge(int seconds);改变保存时间,单位:秒

seconds>0:cookie的数据保存在硬盘中,当超过指定的时间,cookie数据被删除
seconds<0:默认情况,cookie数据保存在内存中,只要浏览器不关闭,数据就一直存在
seconds=0:立即删除cookie数据

路径问题

//浏览器向服务器发送请求时,会比较访问组件的路径与cookie的路径是否匹配,只有匹配成功的cookie,才
//会发送给服务器。
//匹配规则:访问组件的路径必须与cookie的路径相等或者是其子路径
 
cookie的默认路径是创建cookie组件的路径,可以设置cookie的路径,
cookie.setPath("/appname"),让所有的组件都能够访问到cookie

限制

  1. cookie可以被用户禁止
  2. cookie保存的数据大小有限制(4k左右)
  3. cookie保存的个数有限制(300个左右)
  4. cookie保存的数据类型比较有限,只能存字符串
  5. 不安全

基本使用

记录上次登录的时间、保存中文的cookie并显示到客户端

package servlet;

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;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

public class CookieDemo extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        PrintWriter out = resp.getWriter();

        //服务器从客户端获取
        Cookie[] cookies = req.getCookies();//返回的是数组,因为cookie可能存在多个
        //判断cookie是否存在
        if (cookies != null) {
            out.write("上一次访问的时间:");
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                //获取cookie的名字,key
                if (cookie.getName().equals("lastTime")) {
                    //获取cookie的值
                    long parseLong = Long.parseLong(cookie.getValue());
                    Date date = new Date(parseLong);
                    out.write(date.toLocaleString());
                }
                if (cookie.getName().equals("name")) {
                    String value = cookie.getValue();
                    out.write(value);
                }
            }
        } else {
            out.write("第一次访问");
        }

        //服务器给客户端一个cookie
        Cookie cookie = new Cookie("lastTime", System.currentTimeMillis() + "");
        cookie.setMaxAge(24 * 60 * 60);//设置有效期
        resp.addCookie(cookie);
        //中文的cookie
        Cookie cookie1 = new Cookie("name", "校长");
        resp.addCookie(cookie1);
    }
}

练习

需求

写一个FindAddCookieServlet,查找一个名字叫city的cookie,如果找到,输出该cookie的值,
反之,创建一个cookie(city=nj)

写一个CookieUtil,添加三个方法,分别是添加cookie,查找cookie,删除cookie

 public static void addCookie(String name,String value){
     new Cookie(name,value);
 }
 public static String findCookie(){}
 public static void delCookie(){}

使用CookieUtil重构FindAddCookieServlet

代码实现

package cookie;

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;
import java.io.IOException;

/**
 * 写一个FindAddCookieServlet,查找一个名字叫city的cookie,如果找到,输出该cookie的值,
 * 反之,创建一个cookie(city=nj)
 */
@WebServlet("/filter/FindAddCookieServlet")
public class FindAddCookieServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        boolean flag = false;

        if (cookies == null) {
            Cookie cookie = new Cookie("city", "nj");
            resp.addCookie(cookie);
            flag = true;
            resp.getWriter().write(cookie.getName() + ":" + cookie.getValue());
        } else {
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                if (cookie.getName().equals("city")) {
                    System.out.println(cookie.getValue());
                    flag = true;
                    resp.getWriter().write(cookie.getName() + ":" + cookie.getValue());
                }
                if (i == cookies.length - 1 && false == flag) {
                    Cookie cookie1 = new Cookie("city", "nj");
                    resp.addCookie(cookie1);
                    flag = true;
                    resp.getWriter().write(cookie.getName() + ":" + cookie.getValue());
                }
            }
        }
    }
}

重构

package util;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class CookieUtil extends HttpServlet {
    public static void addCookie(HttpServletResponse response, String name, String value, Integer time) {
        Cookie cookie = null;
        try {
            cookie = new Cookie(name, URLEncoder.encode(value,"UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        cookie.setMaxAge(time);
        response.addCookie(cookie);
    }

    public static Cookie findCookie(HttpServletRequest request, HttpServletResponse response, String key) throws IOException {
        Cookie[] cookies = request.getCookies();
        if (cookies == null) {
        } else {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(key)) {
                    return cookie;
                }
            }
        }
        return null;
    }

    public static void delCookie(HttpServletResponse response, String name, String value) {
        addCookie(response, name, value, 0);
    }
}
package cookie;

import util.CookieUtil;

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;
import java.io.IOException;

/**
 * 重构FindAddCookieServlet
 */
@WebServlet("/filter/FindAddCookieServlet1")
public class FindAddCookieServlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if (CookieUtil.findCookie(req, resp, "uuu") == null) {
            resp.getWriter().write("没有,正在创建");
            CookieUtil.addCookie(resp, "uuu", "uuu", 10);
        } else {
            Cookie cookie = CookieUtil.findCookie(req, resp, "uuu");
            resp.getWriter().write(cookie.getName() + ":" + cookie.getValue());
        }
    }
}

Session

什么是session

​ 浏览器向服务器发送请求,服务器会创建一个session对象(该对象有一个唯一的标识sessionId),将sessionId通过set-cookie消息头的方式发送给浏览器,浏览器会将其保存在内存中,当浏览器再次向服务器发送请求时,会将sessionId通过cookie消息头的方式发送给服务器,在服务端,根据sessionId可以查找到session对象,从而可以获取到session对象中绑定的数据,通过此方式实现状态管理的目的。

在这里插入图片描述

使用场景

  • 保存一个登录用户的信息
  • 购物车信息
  • 在整个网站中经常会使用的数据,将它保存到session中

获取session

//方式一
HttpSession session = request.getSession(boolean flag);	
flag = true
    //服务器检查请求数据包中是否含有sessionID,如果没有,创建新的session对象
    //如果有,根据sessionID查询session,找到了不创建,找不到则创建新的session对象
flag = false
    //服务器会检查请求数据包中是否包含sessionId,如果没有,则返回空
  	//如果有,则根据sessionId查找session对象,找到了,返回session对象,找不到,返回空
    
//方式二
HttpSession session = request.getSession();	//等价于flag = true

相关接口、方法

//获取session对象的id	String类型
session.getId();	

//绑定数据
session.setAttribute(String name,Object obj);	

//根据绑定名获取绑定值	Object类型
session.getAttribute(String name);

//删除
session.invalidate();

超时

服务器会将超出指定时间的session对象移除,默认是30分钟(Tomcat设置的),但是可以通过以下方式修改

  1. 修改tomcat/conf/web.xml文件配置参数,单位:分钟

    <session-config>
    	<session-timeout>30</session-timeout>
    </session-config>
    
  2. 修改某个应用的web.xml文件,添加session-config的配置,该应用下所有session超时时间都被统一修改,单位:分钟

  3. 修改某一个session对象的超时时间,单位:秒

    session.setMaxInactiveInterval(int seconds);
    

验证

  1. 作用:只有登录成功之后,才能访问受保护的页面。
  2. 实现方式
    • 登录成功之后,将用户的信息绑定到session上
    • 在访问受保护的页面,校验session对象上是否有用户登录的信息
      • 有:继续访问后续的组件
      • 没有:跳转到登录页面

基本使用

设置

package servlet;

import pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/setSession")
public class SetSession extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
		
        //得到session
        HttpSession session = req.getSession();
        //给session添加数据
        session.setAttribute("name", "校长");
        session.setAttribute("person", new Person("张三", "123"));
        //获取sessionId
        String sessionId = session.getId();
        //判断是否是新创建的
        if (session.isNew()) {
            resp.getWriter().write("sessio创建成功,ID:" + sessionId);
        } else {
            resp.getWriter().write("session在服务器在已经创建,ID:" + sessionId);
        }
    }
}

在这里插入图片描述

获取

package servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/getSession")
public class getSession extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
		
        //获取session
        HttpSession session = req.getSession();
		
        //拿数据
        String name = (String) session.getAttribute("name");
        Person person = (Person) session.getAttribute("person");
        System.out.println(name);
        System.out.println(person);
    }
}

注销

package servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/removeSession")
public class removeSession extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("name");	//移除数据
        session.invalidate();   //手动注销
    }
}

自动过期

<!--设置Session默认的失效时间-->
<session-config>
  <!--15分钟后Session自动失效,以分钟为单位-->
  <session-timeout>15</session-timeout>
</session-config>

异同

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存 (可以保存多个)
  • Session把用户的数据写到用户独占Session中,服务器端保存 (保存重要的信息,减少服务器资源的浪费)
  • Session对象由服务创建;

URL重写

​ 用户可以禁止cookie,禁止了cookie之后,sessionId不再保存在浏览器的内存中,影响session对象的使用,所以需要URL重写。

如何URL重写?

  • 链接、表单:

    <a href="<%=response.encodeURL("地址")%>"></a>
    <form action="<%=response.encodeURL("地址")%>">
    
  • 重定向

    resp.sendRedirect(resp.encodeRedirectURL("otherSession"));
    

ession-timeout>


# **异同**

- Cookie是把用户的数据写给用户的浏览器,浏览器保存 (可以保存多个)
- Session把用户的数据写到用户独占Session中,服务器端保存 (保存重要的信息,减少服务器资源的浪费)
- Session对象由服务创建;

# URL重写

​		用户可以禁止cookie,禁止了cookie之后,sessionId不再保存在浏览器的内存中,影响session对象的使用,所以需要URL重写。

**如何URL重写?**

- 链接、表单:

    ```jsp
    <a href="<%=response.encodeURL("地址")%>"></a>
    <form action="<%=response.encodeURL("地址")%>">
    ```

- 重定向

    ```
    resp.sendRedirect(resp.encodeRedirectURL("otherSession"));
    ```

- 转发:不需要URL重写
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值