9.19JavaWeb之ServletCookie

9.19JavaWeb之ServletCookie

为什么需要Cookie?

原因:

  • Http是一个基于请求和响应模式的无状态协议

什么是无状态协议?

  1. 协议对于事务处理没有记忆能力,服务器不能自动维护用户的上下文信息,无法保存用户状态

  2. 每次请求都是独立的,不会受到前面请求的影响,不会影响后面的请求

举例描述:

浏览器发送Http请求到服务器,服务器响应客服端请求。但同一个浏览器再次发送请求到该服务器,由于Http协议的请求无法保存用户状态。所以就有了会话技术(cookie-session)

会话技术

什么是会话?

从打开浏览器访问某个网站开始,到关闭浏览器的过程

什么是会话技术?

指在会话中,帮助服务器记录用户状态和数据的技术

会话技术分类

  • 客户端会话技术--->Cookie

  • 服务端会话技术--->Session

Cookie

Cookie的产生过程以及工作原理:

  1. 服务器发送给浏览器的小段文本信息,存储在客户端浏览器的内存中或硬盘上

  2. 浏览器保存了 Cookie 后,每次访问服务器,都会在 HTTP 请求头中将这个 Cookie 回传给服务器

Cookie的分类:

  1. 会话级Cookie(默认):Cookie 保存到浏览器的内存中,浏览器关闭则 Cookie 失效。

  2. 持久级Cookie:Cookie以文本文件的形式保存到硬盘上

Cookie的工作原理:

 

注意分清楚次数:

  • 第一次请求:请求当中没有Cookie信息,响应当中会增加Set-Cookie字段

  • 第一次请求后:浏览器将 Cookie 保存在内存中或硬盘上

  • 第一次以后的请求:Request携带Cookie信息,每一次Cookie会自增以便于记录状态和数据

CookieAPI

javax.servlet.http 包中定义了一个 Cookie 类,利用它的带参构造方法,可以创建 Cookie 对象。

方法示例:

Cookie c = new Cookie("name", "value");

注意:

  • nameCookie的名称

  • valueCookie的值

HttpServletResponse 接口和 HttpServletRequest 接口也都定义了与 Cookie 相关的方法:

方法描述所属接口
void addCookie(Cookie cookie) 用于在响应头中增加一个相应的 Set-Cookie 头字段。 javax.servlet.http.HttpServletResponse
Cookie[] getCookies() 用于获取客户端提交的 Cookie。 javax.servlet.http.HttpServletRequest

javax.servlet.http.Cookie 类中提供了一系列获取或者设置 Cookie 的方法:

返回值类型方法描述
int getMaxAge() 用于获取指定 Cookie 的最大有效时间,以秒为单位。 默认情况下取值为 -1,表示该 Cookie 保留到浏览器关闭为止。
String getName() 用于获取 Cookie 的名称。
String getPath() 用于获取 Cookie 的有效路径。
boolean getSecure() 如果浏览器只通过安全协议发送 Cookie,则返回 true;如果浏览器可以使用任何协议发送 Cookie,则返回 false。
String getValue() 用于获取 Cookie 的值。
int getVersion() 用于获取 Cookie 遵守的协议版本。
void setMaxAge(int expiry) 用于设置 Cookie 的最大有效时间,以秒为单位。 取值为正值时,表示 Cookie 在经过指定时间后过期。取值为负值时,表示 Cookie 不会被持久存储,在 Web 浏览器退出时删除。取值为 0 时,表示删除该 Cookie。--->Important
void setPath(String uri) 用于指定 Cookie 的路径。
void setSecure(boolean flag) 用于设置浏览器是否只能使用安全协议(如 HTTPS 或 SSL)发送 Cookie。--->Important
void setValue(String newValue) 用于设置 Cookie 的值。--->Important
Cookie使用的细节
  • 一个Cookie只能标识一种信息,至少包含一个Name和一个Value--->Cookie用于标识的是服务端的信息,而不是用户的身份

  • Cookie默认是会话级的,需要设置成持久级的调用setMaxAge(int maxAge)方法,单位为秒

  • 手动删除 Cookie时,需要使用 setPath 方法指定 Cookie 的路径,且该路径必须与创建 Cookie 时的路径保持一致--->WebServlet注释的地址

Cookie的缺点
  • 在Http请求中Cookie是明文传输的。安全性不高。

  • 浏览器可以禁用Cookie

  • Cookie 对象中只能设置文本(字符串)信息

  • 客户端浏览器保存 Cookie 的数量和长度是有限制的

示例代码:

Cookie设置类:

package com.example.HttpServletRequestDemo;

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.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
* 获取Cookie或设置Cookie的类
* @since JDK 1.8
* @date 2021/09/20
* @author Lucifer
*/
@WebServlet(name = "LoginTime", value = "/LoginTime")
public class LoginTimeServlet extends HttpServlet {
   //设置UID
   private static final long serialVersionUID = -5604481158386227221L;

   //Get方法
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //设置响应字符集
       resp.setContentType("text/html;charset=UTF-8");
       /**
        * 1、获取Cookie判断是否为空进而判断是否是第一次访问
        */
       //获取所有的Cookie--->Cookie数组
       Cookie[] cookies = req.getCookies();
       //通过Cookie名称来查找cookie--->Cookie列表+Cookie名称
       Cookie cookie = getCookieByName(cookies, "lastTime");
       if (cookie == null){
           //输出内容
           resp.getWriter().write(
                   "<h1>JunkingBoy</h1>"
                   + "<h3>Welcome!!!</h3>"
          );
      }else {
           //获取Cookie,输出内容
           getCookieAndValue(cookie, resp);
      }
       //记录当前时间
       Date date = new Date();
       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
       String sDate = sdf.format(date);
       //写回到浏览器
       //使用Cookie回写(cookie的值中含有 “ ”,需要进行编码才能使用)--->设置编码
       Cookie c = new Cookie("lastTime", URLEncoder.encode(sDate));
       //设置Cookie有效期
       c.setMaxAge(60 * 60 * 24);
       //设置有效路径
       c.setPath("/HttpServletRequestDemo");
       //回写
       resp.addCookie(c);
  }

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

   //获取Cookie,输出内容
   private static void getCookieAndValue(Cookie cookie, HttpServletResponse resp) throws IOException {
       //获取Cookie
       String value = cookie.getValue();
       //输出内容
       resp.getWriter().write(
               "<h3>JunkingBoy,欢迎您的归来!</h3><h3>上次登录时间是:"
                       + URLDecoder.decode(value) + "</h3>"
                       + "<a href=\"removeCookie\">清楚Cookie</a>"
      );
  }

   //getCookieByName方法,通过Cookie列表和要查找的Cookie名称
   private static Cookie getCookieByName(Cookie[] cookies, String name){
       //判断数组是否为空
       if (cookies == null){
           return null;
      }else {
           //循环遍历目录与name做比较
           for (Cookie cookie : cookies){
               //如果和形参相等那么就输出
               if (cookie.getName().equals(name)){
                   return cookie;
              }
          }
      }
       //如果遍历完都没有,返回空
       return null;
  }
}

删除Cookie:

package com.example.HttpServletRequestDemo;

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;

/**
* 删除Cookie
* @since JDK 1.8
* @date 2021/09/20
* @author Lucifer
*/
@WebServlet(name = "removeCookie", value = "/removeCookie")
public class RemoveCookieServlet extends HttpServlet {
   //设置UID
   private static final long serialVersionUID = 1L;

   //Get
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //获取Cookie
       Cookie cookie = new Cookie("lastTime", "");
       //设置有效时间为0,删除Cookie
       cookie.setMaxAge(0);
       //设置有效路径,要与目录路径一致
       cookie.setPath("/HttpServletRequestDemo");
       //回写
       resp.addCookie(cookie);
       //重定向商品列表页面
       resp.sendRedirect("/HttpServletRequestDemo/LoginTime");
  }

   //Post
   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req, resp);
  }
}
posted @ 2021-09-20 20:05  俊king  阅读(132)  评论(0编辑  收藏  举报