JavaWeb-Cookie与Session

一、概念

是否还记得我们在HTTP概念中提到:HTTP的一大特点是无状态,这意味着多次HTTP请求之间是无法共享数据的。而在请求之间共享一些数据又是我们期望达到的效果。(例如登录的记住我功能)于是便有了会话跟踪技术,而Cookie与Session就是两种实现方式。

二、Cookie

Cookie:客户端会话跟踪技术,客户端第一次请求服务端时,服务端会生成一个Cookie,并返回给客户端。此Cookie会保存在客户端,并且在以后每次请求中都携带Cookie访问服务端。

(1) 服务端生成Cookie并返回给客户端
package com.byhuang.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;@WebServlet("/aServlet")
public class AServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Cookie cookie = new Cookie("name", "value");resp.addCookie(cookie);}
}
(2)再次请求服务端时,将携带Cookie访问。在服务端接收Cookie:
package com.byhuang.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;@WebServlet("/bServlet")
public class BServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Cookie[] cookies = req.getCookies();for (Cookie cookie : cookies) {if ("name".equals(cookie.getName())) {System.out.println("here:" + cookie.getName() + cookie.getValue());}}}
}
(3) 原理

Cookie的实现是基于HTTP协议的。Web服务器中会在响应头里设置setCookie字段,值为key=value。在上面的例子中,就是setCookie: name=value;当客户端下次请求服务端时,会在请求头中添加Cookie字段,值为所有Cookie的键值对,并用分号分割。如下图所示:

(4) Cookie使用细节

默认情况下,Cookie存储在浏览器的内存中,会随着浏览器的关闭而销毁。但是例如记住我这种功能,不可能要求用户的浏览器保持不关闭。相关API给我们提供了方法:

setMaxAge(int seconds): 参数表示让这个Cookie的存活时间(单位秒),即使关闭浏览器,也会持久化存储在硬盘中,下次打开浏览器Cookie依然是有效的。参数为0表示立即删除这个Cookie,Cookie为负数表示

三、Session

Session:服务端会话跟踪技术:将数据保存在服务端。Java提供了HttpSession接口,来实现一次会话的多次请求之间的数据共享。

(1) 服务端生成session
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("/asession")
public class ASession extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HttpSession session = req.getSession();System.out.println(session);session.setAttribute("user", "zs");}
}
(2)客户端在同一个会话中再次请求服务端时,可以取到同一个session,并取到在上一次请求传递的值。
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("/bsession")
public class BSession extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HttpSession session = req.getSession();System.out.println(session); // 打印的Seesion与第一次请求时打印的相同String username = (String) session.getAttribute("user");System.out.println(username);  // 取出第一次请求时设置的值,实现了会话间数据共享}
}
(3)原理

Session是基于Cookie实现。Web服务器(如Tomcat)会自动把session id以Cookie的形式发送给客户端,客户端在下次请求时,会携带该session id访问。于是在下次获取session时,可以根据这一session id找到在上一次访问的HttpSession对象。而其它客户端的session id与该id不同,于是就实现了在同一会话中,通过session共享数据的目的。

(4) session的使用细节

session的钝化、活化:我们上面提到session是存储在服务端的,也就是session存储在服务器的内存中的。那么在服务器重启后,内存被销毁,session就消失了。但是session有钝化机制,也就是说,当服务器正常关闭时,还存活着的session(在设置时间内没有销毁) 会随着服务器的关闭被以文件(“SESSIONS.ser”)的形式存储在tomcat 的work 目录下,这个过程叫做Session 的钝化。而活化是指重启服务器后,从文件中加载数据到session中。

session的销毁:我们日常生活中也有登出的功能,这里就需要用到session的销毁机制。可以用session.invalidate()方法来实现,读者可自由尝试,笔者在这里不再提供演示。

四、cookie与session的对比
  1. 存储位置:cookie是存储在客户端,session是存储在服务端
  2. 安全性:由于存储位置的区别,因此cookie更不安全
  3. 数据大小:cookie最大是3KB,session无大小限制
  4. 存储时间:cookie可以长期存储,session默认30分钟
  5. 服务器性能:由于session存储在服务端,所以会占用服务器资源

根据以上的对比,我们来看以下几个场景,我们应该使用cookie还是session呢(重要)

(1)早期购物网站的购物车,是在登录前也可以加入商品的。在下次进入网站时,此前加入的商品依然可以显示出来。

分析:这个场景下,肯定是要求客户端被关闭后,再次打开时依然能够取到数据。那这样的话session就不能满足了,因为session id作为cookie存储在客户端,会随着客户端的关闭而销毁(session id通常不会持久化在硬盘中);因此会使用cookie将购物车里的数据持久到本地的硬盘里,下次打开时重新加载进浏览器中。有读者可能会有疑问,session id不是cookie吗,不能把这个cookie的过期时间设置的久一些,然后持久化在客户端中吗?要知道,session id作为cookie是Web服务器(如Tomcat)替我们完成的,我们不能简便去修改这个动作。当然我们也可以在Web项目中设置全局的session的过期时间,但是这似乎会影响到其它功能,比如说下面第(2)个场景。因此,还是需要使用cookie,而非去修改session的默认超时时间。多说一句,现在购物车的功能大多都修改为存储在数据库中,这也就意味着在登录前取消了加入购物车的这一功能。

(2)登录成功之后的用户数据

分析:由于cookie需要频繁地在客户端与服务端传递,显然是不安全的,而用户信息显然是敏感数据,毫无疑问,这个场景需要使用session。

(3)记住我功能

分析:这个也是需要关闭浏览器再重新打开后依然生效的,因此也需要保存在cookie中。但是这个也需要传递用户数据,因此强行实现这个功能是不安全的,所以目前许多网站都逐渐取消了这人曾经风靡一时的功能。

(4)图片验证码,在注册或登录时,常常会遇到输入完用户名和密码后填写一个图形验证码的场景,比如需要输入图片中的几个数字。

分析:使用图片验证码正是为了有人恶意攻击,比如暴力尝试密码、暴力注册大量用户攻击服务器数据库等。如果使用cookie,相当于把答案传递给了客户端,所以“答案”(数据)只能保存在服务端,使用session。

以上便是对cookie和session的介绍,接下来,笔者将会用本篇的知识来实现一个用户登录、注册、记住我、验证码的小demo,请读者继续关注。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/418005.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql 下载和安装和修改MYSQL8.0 数据库存储文件的路径

一、第一步:下载步骤 下载链接:MySQL :: Download MySQL Installer 选择版本8.0.35,社区版, 点击 Download 下载 安装包 二、第二步:安装步骤 添加环境变量,C:\Program Files\MySQL\MySQL Server 8.0\bin 可以点开MySQL 8.0 Co…

基于python socket实现TCP/UDP通信

两个应用程序如果需要进行通讯最基本的一个前提就是能够唯一的标示一个进程,我们知道IP层的ip地址可以唯一标示主机,而TCP层协议和端口号可以唯一标示主机的一个进程,这样我们可以利用ip地址+协议+端口号唯一标示网络中…

【蓝桥杯EDA设计与开发】立创开源社区分享的关于蓝桥被EDA真题与仿真题的项目分析

立创开源社区内有几个项目分享了往年 EDA 设计题目与仿真题,对此展开了学习。 【本人非科班出身,以下对项目的学习仅在我的眼界范围内发表意见,如有错误,请指正。】 项目一 来源:第十四届蓝桥杯EDA赛模拟题一 - 嘉立…

掌握使用CXF快速开发webservice服务和生成client端技能

文章目录 前言1.安装和配置cxf环境2.创建一个通过maven管理的java项目并引入相关cxf依赖3.使用cxf提供的类编写webservice服务端并发布服务3.1 定义一个webservice服务接口HelloWorld3.2 编写HelloWorld实现类3.3 通过JaxWsServerFactoryBean发布webservice服务3.4 在浏览器中通…

实用干货:最全的Loading动画合集网站!复制即用

大家好,我是大澈! 本文约1000字,整篇阅读大约需要2分钟。 感谢关注微信公众号:“程序员大澈”,免费领取"面试礼包"一份,然后免费加入问答群,从此让解决问题的你不再孤单&#xff01…

写点啥 内核调优吧

一、命令xargs --------------- 参数替换 由于很多命令不支持管道|来传递参数,xargs用于产生某个命令的参数,xargs 可以读入 stdin 的数 据,并且以空格符或回车符将 stdin 的数据分隔成为参数,另外许多命令不能接受过多参数&am…

【Linux】相关背景及环境搭建

前言: 认识 Linux, 了解 Linux 的相关背景,学会如何使用云服务器,掌握使用远程终端工具 xshell 登陆 Linux 服务器 文章目录 一、Linux介绍1.1 关于UNIX1.2 Linux的诞生及发展历程1.3 Linux开源1.4 Linux在各个行业的现状1.5 发行版本 二、Li…

【设计模式】腾讯二面:自动贩卖机/音频播放器使用了什么设计模式?

状态模式是什么? 状态模式,也被称作状态对象模式,是一种行为设计模式。 当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。 它让对象在其内部状态改变时改变自己的行为。外部调用者无需了…

Docker(八)高级网络配置

作者主页: 正函数的个人主页 文章收录专栏: Docker 欢迎大家点赞 👍 收藏 ⭐ 加关注哦! 高级网络配置 注意:本章属于 Docker 高级配置,如果您是初学者,您可以暂时跳过本章节,直接学习…

8 python快速上手

总结 总结1. 代码规范1.1 名称1.2 注释1.3 todo1.4 条件嵌套1.5 简单逻辑先处理1.6 循环1.7 变量和值 2.知识补充2.1 pass2.2 is 比较2.3 位运算 3.阶段总结 各位小伙伴想要博客相关资料的话关注公众号:chuanyeTry即可领取相关资料! 总结 1. 代码规范 …

安卓平板局域网内远程控制工控机方法

安卓平板局域网内远程控制工控机方法 将所需要远程控制的工控机通过网线连接到具有WiFi功能的路由器上,将安卓平板连接上WiFi,如下图所示 下载NoMachine远程软件安装包,官网地址:https://www.nomachine.com/ 点击Download now按钮…

Hive数仓框架详解

Hive框架详解 1、Hive的介绍 ​ Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。 ​ 本质是将SQL转换为MapReduce程序。 ​ 主要用途:用来做离线数据分析,比直接用MapRed…