Servlet【 ServletAPI中的会话管理Cookie与Session】

news2025/7/14 21:38:28

Servlet【 ServletAPI中的会话管理Cookie与Session】

  • 🍒一.回顾Cookie与Session
    • 🍎1.1 Cookie
    • 🍎1.2 Session
    • 🍎1.3Cookie 和 Session 的区别
  • 🍒二.Servlet会话管理操作
    • 🍎2.1核心方法
  • 🍒三.常见案例实现
    • 🍎3.1登录逻辑的实现
    • 🍎3.2上传文件

🍒一.回顾Cookie与Session

🍎1.1 Cookie

HTTP 协议自身是属于 “无状态” 协议.

“无状态” 的含义指的是:
默认情况下 HTTP 协议的客户端和服务器之间的这次通信, 和下次通信之间没有直接的联系.但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的.
例如登陆网站成功后, 第二次访问的时候服务器就能知道该请求是否是已经登陆过了

回忆之前的例子:

  1. 到了医院先挂号. 挂号时候需要提供身份证, 同时得到了一张 "就诊卡"Cookie, 这个就诊卡就相当于患者的 “令牌”.
  2. 后续去各个科室进行检查, 诊断, 开药等操作, 都不必再出示身份证了, 只要凭就诊卡即可识别出当前患者的身份.
  3. 看完病了之后, 不想要就诊卡了, 就可以注销这个卡. 此时患者的身份和就诊卡的关联就销毁了. (类似于网站的注销操作)
  4. 又来看病, 可以办一张新的就诊卡, 此时就得到了一个新的 “令牌”

此时在服务器这边就需要记录令牌信息, 以及令牌对应的用户信息, 这个就是 Session 机制所做的工作

🍎1.2 Session

服务器同一时刻收到的请求是很多的. 服务器需要清除的区分清楚每个请求是从属于哪个用户, 就需要在服务器这边记录每个用户令牌以及用户的信息的对应关系.在上面的例子中, 就诊卡就是一张 “令牌”. 要想让这个令牌能够生效, 就需要医院这边通过系统记录每个就诊卡和患者信息之间的关联关系.

会话的本质就是一个 “哈希表”, 存储了一些键值对结构. key 就是令牌的 ID(token/sessionId), value 就是用户信息(用户信息可以根据需求灵活设计).
sessionId 是由服务器生成的一个 “唯一性字符串”, 从 session 机制的角度来看, 这个唯一性字符串称为 “sessionId”. 但是站在整个登录流程中看待, 也可以把这个唯一性字符串称为 “token”.sessionId 和 token 就可以理解成是同一个东西的不同叫法(不同视角的叫法)

用户登陆:
●当用户登陆的时候, 服务器在 Session 中新增一个新记录, 并把 sessionId / token 返回给客户端.(例如通过 HTTP 响应中的 Set-Cookie 字段返回).
●客户端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId/ token. (例如通过 HTTP 请求中的 Cookie 字段带上).
●服务器收到请求之后, 根据请求中的 sessionId / token 在 Session 信息中获取到对应的用户信息,再进行后续操作.

Servlet 的 Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失.

🍎1.3Cookie 和 Session 的区别

●Cookie 是客户端的机制. Session 是服务器端的机制.
●Cookie 和 Session 经常会在一起配合使用. 但是不是必须配合.
●完全可以用 Cookie 来保存一些数据在客户端. 这些数据不一定是用户身份信息, 也不一定是token / sessionId
●Session 中的 token / sessionId 也不需要非得通过 Cookie / Set-Cookie 传递.

🍒二.Servlet会话管理操作

在这里插入图片描述

🍎2.1核心方法

HttpServletRequest 类中的相关方法

方法描述
HttpSession getSession()在服务器中获取会话. 参数如果为 true, 则当不存在会话时新建会话; 参数如果为 false, 则当不存在会话时返回 null
Cookie[] getCookies()返回一个数组, 包含客户端发送该请求的所有的 Cookie 对象. 会自动把Cookie 中的格式解析成键值对.
Part getPart(String name)获取请求中给定 name 的文件
Collection getParts()获取所有的文件

HttpServletResponse 类中的相关方法

方法描述
void addCookie(Cookie cookie)把指定的 cookie 添加到响应中.

HttpSession 类中的相关方法
一个 HttpSession 对象里面包含多个键值对. 我们可以往 HttpSession 中存任何我们需要的信息.

方法描述
Object getAttribute(Stringname)该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null.
void setAttribute(Stringname, Object value)该方法使用指定的名称绑定一个对象到该 session 会话
boolean isNew()判定当前是否是新创建出的会话

Cookie 类中的相关方法
每个 Cookie 对象就是一个键值对.

方法描述
String getName())该方法返回 cookie 的名称。名称在创建后不能改变。(这个值是 SetCooke 字段设置给浏览器的)
String getValue()该方法获取与 cookie 关联的值
void setValue(String newValue)该方法设置与 cookie 关联的值

HTTP 的 Cooke 字段中存储的实际上是多组键值对. 每个键值对在 Servlet 中都对应了一个 Cookie对象.
●通过 HttpServletRequest.getCookies() 获取到请求中的一系列 Cookie 键值对.
●通过 HttpServletResponse.addCookie() 可以向响应中添加新的 Cookie 键值对.

Part 类方法

方法描述
String getSubmittedFileName()获取提交的文件名
String getContentType()获取提交的文件类型
long getSize()获取文件的大小
void write(String path)把提交的文件数据写入磁盘文件

🍒三.常见案例实现

🍎3.1登录逻辑的实现

我们经常上网查询一些网站什么的,很多网站都会让你先登录,才能使用其中的一些功能,登录完成之后,一般都会跳到一个主页网站,下面我们就来简单地实现一下这一套逻辑。

第一步,约定前后端接口
我们需要实现两套交互逻辑,一是登录跳转,二是获取主页

登录跳转约定:
约定使用POST请求,响应采用302重定向
在这里插入图片描述
获取主页约定:
采用GET请求,响应返回一个页面
在这里插入图片描述
在这里插入图片描述
第二步,编写前端交互页面
我们的重点是来学习登录的逻辑,因此登录的界面不需要很好看很复杂,只要能够有两个输入框和一个提交按钮让我们输入账号密码就行。目标页面如下:
在这里插入图片描述
在pom.xml中引入Servlet依赖

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

前端代码

<!DOCTYPE html>
<html lang="ch">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body>
<form action="login" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit" value="登录">
</form>
</body>
</html>

后端代码登陆

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("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf8");
        resp.setCharacterEncoding("utf8");
        //获取用户账号
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //验证账户
        //验证按照正常流程应该从数据库读数据,但是为了便于演示登录的逻辑,我们直接将账号密码写死
        //假设正确的账号与密码是 zhangsan 123
        if ("zhangsan".equals(username) && "123".equals(password)) {
            //登录成功
            //创建会话,为后续需登录的页面做准备
            HttpSession httpSession = req.getSession(true);
            httpSession.setAttribute("username", username);
            //初始情况下设置登录次数
            httpSession.setAttribute("count", 0);
            //跳转到目标页面index
            resp.sendRedirect("index");
        } else {
            //登录失败
            resp.getWriter().write("登录失败!");
        }
    }
}

登陆后重定向页面响应

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("/index")
public class IndexServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //返回一个主页
        //获取会话,参数必须是false
        HttpSession httpSession = req.getSession(false);
        //取出会话信息
        String username = (String) httpSession.getAttribute("username");
        Integer cnt = (Integer) httpSession.getAttribute("count");
        //访问次数加1
        cnt++;
        //写回到会话中
        httpSession.setAttribute("count", cnt);

        //构造页面。我们简单构造一下就好
        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write("<h3>欢迎您!" + username + "</h3> <h4>这个主页已经被访问了" + cnt + "次</h4>");
    }
}

在这里插入图片描述

🍎3.2上传文件

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>file</title>
</head>
<body>
<form action="upload" method="post" enctype="multipart/form-data">
    <input type="file" name="myfile">
    <input type="submit" value="提交">
</form>

</body>
</html>

后端代码

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

@MultipartConfig
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取Part对象
        Part part = req.getPart("myfile");
        //输出文件信息
        //文件名
        System.out.println("文件名:" + part.getSubmittedFileName());
        //文件类型
        System.out.println("文件类型:" + part.getContentType());
        //文件大小
        System.out.println("文件大小:" + part.getSize());
        //将文件写入磁盘
        part.write("D:\\上传文件");
        //返回响应
        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write("上传成功!");
    }
}

在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【服务器搭建】教程一:没钱买服务器怎么玩 进来看

前言&#xff1a; 最近看到有一些网上的大佬把自己的爱心网页&#xff08;没领到的小伙伴看一下前几篇文章&#xff09;部署到了自己的服务器上&#xff0c;使得可以直接通过链接就实现访问。属实不错&#xff01; 自己内心就产生了这样一个想法&#xff1a;购买一台服务器&a…

Whisper论文阅读笔记

Whisper论文阅读笔记Robust Speech Recognition via Large-Scale Weak Supervision1. 引言2. 方法2.1 数据处理2.2 模型2.3 多任务设置2.4 训练细节3. 实验结果3.1 Zero-shot3.2 多语言语音识别3.3 多语言机器翻译3.4 语种检测3.5 对加性噪声的鲁棒性3.6 长语音转录3.7 人类基线…

基于向量加权平均值的高效优化算法(Matlab代码实现)

&#x1f4dd;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;…

学习 RabbitMQ 这一篇就够了

文章目录一、MQ相关概念二、RabbitMQ相关概念三、安装四、HelloWorld五、工作队列5.1、轮询分发消息5.2、消息应答5.2.1、自动应答5.2.2、手动应答5.2.3、消息自动重新入队5.2.4、消息手动应答代码5.3、持久化5.4、不公平分发&#xff08;能者多劳&#xff09;5.5、预取值5.6、…

读书笔记3|使用Python,networkx对卡勒德胡赛尼三部曲之——《群山回唱》人物关系图谱绘制

读书笔记3|《群山回唱》-卡勒德胡赛尼 踉跄前行中&#xff0c;你总能在他们身上找到丢失的那一部分记忆。 一度看不下去这本书&#xff0c;因为最开始的章节里太痛了&#xff0c;加上我也离开我的孩子&#xff0c;生活已经够苦&#xff0c;我需要一点糖。这次实在太无聊了&…

php-上传图片加水印(文字水印图片水印)

img.php <?php $img 1.jpg; //获取图片信息 $info getimagesize($img); //获取图片类型 $type image_type_to_extension($info[2],false); //在内容中创建一个和图片一模一样的图片 $ext "imagecreatefrom{$type}"; //图片复制到内存中 $image $ext($img);…

基于SpringBoot前后端分离的网吧管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SpringBoot 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目…

PICO《轻世界》体验:随心畅玩,洒脱创作,潜力无限

不少玩家应该还记得&#xff0c;PICO 4发布会上曾宣布将在VR运动健身、VR视频、VR娱乐、VR创造四大方向展开内容布局。而目前&#xff0c;前三个完成了基本部署&#xff0c;在创造方向上则依托于刚刚上线的《轻世界》这款应用。《轻世界》是一款3D内容UGC创作产品&#xff0c;目…

php宝塔部署实战thinkphp考试平台管理系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 有个朋友发消息跟我说&#xff0c;在网上下载了一套thinkphp考试管理系统的源码&#xff0c;在搭建的时候遇到问题一直部署不起来&#xff0c;让我帮他看看&#xff0c;我看了下代码&#xff0c;里面有些部分代码…

2022年11月华南师范大学自考本科网络工程-本科实践题目

《互联网及其应用&#xff08;03142&#xff09;&#xff08;实践&#xff09;》课程试卷 答卷提交说明&#xff1a;编程代码与输出结果截图&#xff0c;放到一个文件中&#xff0c;文件以“序号 姓名 课程名 ”命名&#xff0c;本试卷有三门课程&#xff0c;请根据不同的课程…

k8s训练营

一、linux命名空间和docker 1.linux的7大ns--------------ipc,net,pid,mnt.uts.user 查看linux的ns lsns查看不同类型的ns [rootmaster ~]# lsns -t netNS TYPE NPROCS PID USER COMMAND 4026531956 net 116 1 root /usr/lib/systemd/systemd --system --deserialize …

公司代码全局参数设置及其意义

在SAP中配置公司时&#xff0c;会配置公司的全局参数&#xff0c;但这些参数具体的意思是什么估计很多同学都搞不懂&#xff0c;我也找了下资料&#xff0c;贴出来供大家参考。 设置参数路径&#xff1a;IMG→财务会计→财务会计全局设置→公司代码的全球参数→输入全局参数 账…

C++Qt开发——Linguist语言家

Qt Linguist 简介 Qt提供了一款优秀的支持Qt C和Qt Quick应用程序的翻译工具。发布者、翻译者和开发者可以使用这款工具来完成他们的任务。 发布者&#xff1a;承担了全面发布应用程序的责任。通常&#xff0c;他们协调开发者和翻译者的工作&#xff0c;可以使用lupdate工具…

激光雷达的厮杀18年:西方“诸神黄昏”,东方“新王隐现”

鼻祖、发明家、神童、梦想家、特种兵和中国双星&#xff0c;激光雷达“诸神混战”&#xff0c;行业疯狂洗牌。 风云激荡中&#xff0c;每个人都在亲身见证历史。 2004年&#xff0c;美国发起DARPA挑战赛&#xff0c;无人车上路&#xff0c;汽车上首次出现激光雷达。 2010年之…

原型工具墨刀的使用

刚开始接触原型工具是大学时候了&#xff0c;大学参加大创的时候第一次接触并使用原型工具做了小程序项目原型。那时候是下载的客户端。 最近&#xff0c;又开始思考在用户沟通过程中为方便沟通&#xff0c;可以先自己用原型工具简单的设计一下先。 首先&#xff1a;网页版好用…

JavaScript流程控制-循环(循环(for 循环,双重 for 循环,while 循环,do while 循环,continue break))

目录 JavaScript流程控制-循环 循环 for 循环 执行过程&#xff1a; 断点调试&#xff1a; 案例一&#xff1a;求1-100之间所有整数的累加和 案例二&#xff1a;求1-100之间所有数的平均值 案例三&#xff1a;求1-100之间所有偶数和奇数的和 案例四&#xff1a;求1-10…

哈希(Hash) - 开散列/闭散列

文章目录&#xff1a;认识哈希哈希函数处理冲突的方法闭散列&#xff08;开放定址法&#xff09;开散列&#xff08;链地址法&#xff09;哈希表闭散列实现闭散列基本框架哈希表闭散列插入&#xff08;insert&#xff09;哈希表闭散列删除&#xff08;erase&#xff09;哈希表闭…

深度学习模型部署全流程-模型部署

往期回顾&#xff1a;模型训练 文章目录前言模型部署全流程1.推理框架2.onnx模型3.模型转换4.代码实现5.完整代码小结前言 在上一篇文章中详细讲述了模型训练的流程&#xff0c;这篇文章主要介绍模型部署的流程。模型部署通常指通过C/C语言能够把python框架训练好的模型跑起来…

【ROS】机械人开发一--树莓派安装ubuntu18.04

前言&#xff1a;安装了一天的树莓派系统&#xff0c;遇到了很多坑&#xff0c;这里将教程详细分享一下&#xff0c;方便大家快速的安装系统。 目录一、操作环境硬件软件二、资源下载链接三、具体步骤烧入修改镜像文件问题修改重启时间PC端使用xshell远程连接修改软件源安装ubu…

嵌入式软件调试(Debug)方法

嵌入式软件调试&#xff08;Debug&#xff09;方法1 问题定位和分析方法1.1 二分定位法1.2 数据流方法1.3 隔离法1.4 汇编法1.5 ABA法1.6 版本回溯确认法1.7 调试IO法2 调试注意事项3 典型问题类型1 问题定位和分析方法 1.1 二分定位法 方法阐述&#xff1a; 在任务中或者可能…