【Java EE】-Servlet(四) Cookie和Session

news2025/1/18 6:42:05

作者:学Java的冬瓜
博客主页:☀冬瓜的主页🌙
专栏:【JavaEE】
分享: 寂寞会发慌,孤独是饱满的。——史铁生《命若琴弦》

主要内容:Cookie的理解,Cookie是什么?Cookie从哪里来?到哪里去?Cookie保存在哪里?Session的理解,Session是什么?Session在哪里?Session怎么组织的?Cookie和Session协作完成登录功能。Cookie和Session之间的联系和区别。Cookie和Session实现模拟登录。

在这里插入图片描述

文章目录

  • 一、Cookie和Session
    • 1、Cookie的理解
    • 2、Cookie和Session协作登录
    • 3、Session的理解
    • 4、Cookie和Session之间的关联和区别
  • 三、Cookie和Session模拟登录
    • 1、前端代码
    • 2、后端代码
    • 3、页面展示

一、Cookie和Session

1、Cookie的理解

1> 什么是Cookie?

Cookie是浏览器提供持久化存储数据的机制,可以存储用户的登录信息,购物车内容,浏览历史记录等信息。

2> Cookie从哪里来?

从服务器来。在用户第一次访问服务器时,由服务器生成Cookie,服务器端的代码由服务器的程序员决定,将什么信息保存到客户端(浏览器)这边,是通过Http 响应的Set-Cookie字段,把键值对(保存信息)写进resp的 header,从而发送给浏览器,并且保存在浏览器(客户端的硬盘)上。

3> Cookie往哪里去?

回到服务器。 在后续再次访问服务器时,http请求报文的 header中会加上Cookie,发送给服务器。服务器就可以通过Cookie中的值,来识别当前客户端是哪个,当前客户端的服务提供到哪个环节了。

4> Cookie存储在哪里?

Cookie存储在浏览器(客户端) 所在主机的硬盘中。当用户访问网站生成Cookie时,它会在用户的计算机上创建一个文本文件,并将其存储在浏览器的Cookie存储区域中(该文件在客户端硬盘上),浏览器会定期清理Cookie存储区域,以删除过期的Cookie。

2、Cookie和Session协作登录

Cookie有很多用途,比如,会话管理、个性化体验、广告定向等。在登陆中保存标识用户身份的信息sessionId 是最典型的一个应用。登录功能中,Cookie搭配Session使用,可以做到在定长时间内保持登录功能。

在这里插入图片描述

3、Session的理解

Session存在于服务器端,是SessionId和对应的HttpSession对象的键值对结构。同时HttpSession对象中可以存储程序员自定义的 键值对。

在这里插入图片描述

4、Cookie和Session之间的关联和区别

  • 关联: 在网站登录功能中,需要配合使用
  • 区别:
    1> Cookie是客户端的存储机制,Session是服务器端的存储机制。
    2> Cookie里可以存各种键值对,Session则是专门用来保存用户的身份信息。
    3> Cookie在实现非登陆场景下,可以不搭配Session,单独使用。
    4> Session也可以单独使用,比如手机app登录服务器,服务器使用Session,但是客户端(手机app)这里没有Cookie,因为Cookie是在浏览器中的一种存储机制。
    5> Cookie是Http协议的一部分,Session则和http协议无关(TCP…也可以使用Session)。

三、Cookie和Session模拟登录

需求:需要一个登录页面,点击登录,触发一个登录请求,使用一个LoginServlet来处理这个请求来验证用户名和密码,登录成功,则跳转到主页面。这个主页面可以是一个html静态页面,也可以是Servlet动态构建的页面IndexServlet,再添加一个安全退出的功能。
页面:1> 登陆页面 2> 主页面
servlet: 1>LloginServlet 2> IndexServlet 3> ExitServlet

1、前端代码

login.html作为登陆页面,用户名或密码错误需要重定向回这个页面,安全退出时也重定向到这个页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模拟登录</title>
</head>
<body>
    <form action="./login" method="post">
        <span>username:</span><input type="text" name="username">
        <br>
        <span>password:</span><input type="password" name="password">
        <br>
        <input type="submit" value="submit">

    </form>
</body>
</html>

2、后端代码

LoginServlet.java 处理客户端登陆的请求,进行身份验证,验证成功后保存用户信息到HttpSession对象中,并且重定向到主页面。因为这个servlet是从 login.htm的form表单构造的post请求跳转过来的,所以使用doPost方法处理。

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 {
    // 点击提交时,跳转到当前页面执行doPost方法
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.验证用户身份
        // 这里为了方便,就不再从数据库查找,而是直接规定:username:lihua,password:123 为正确验证
        String userName = req.getParameter("username");
        String passWord = req.getParameter("password");
        // 验证失败
        if (!userName.equals("lihua")){
            // 服务器端打印
            System.out.println("用户名错误!");
            resp.sendRedirect("./login.html");
            return;
        }
        if (!passWord.equals("123")){
            System.out.println("密码错误!");
            resp.sendRedirect("./login.html");
            return;
        }
        // 验证成功
        // 重定向:浏览器重新发送一个get请求给服务器,服务器使用 IndexServlet来处理
        // 使用session保存用户名,让用户名在主页中动态显示
        // 注意:下面中true参数表示:服务器先找有没有当前客户端的会话,有则返回,无则创建再返回
        HttpSession session = req.getSession(true);
        session.setAttribute("username", userName);
        resp.sendRedirect("./index");
    }
}

IndexServlet.java 当通过用户验证,就跳转到主页面,主页面中对保存在当前客户端对应的HttpSession对象中存储的内容进行动态的显示。并提供一个安全退出的按钮。

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 {
        resp.setContentType("text/html; charset=utf-8");
        // 注意:下面中false参数表示:服务器先找有没有当前客户端的会话,有则返回,无则返回null
        HttpSession session = req.getSession(false);
        if(session == null){
            // 用户未登录,跳转到登录页面
            resp.sendRedirect("./login.html");
            return;
        }
        String username = (String) session.getAttribute("username");
        resp.getWriter().write("welcome, " + username);
        // 安全退出的a标签,跳转到 exitServlet处理
        resp.getWriter().write("        <br><a href=\"./exit\">安全退出</a>\n");
    }
}

ExitServlet.java 删除当前客户端session,并且跳转回到登陆页面。这个servlet是从a标签跳转过来的,所以是get请求,使用doGet处理。

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("/exit")
public class ExitServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession(false);
        if (session != null){
            // 删除session,进行安全退出
            session.invalidate();
            resp.sendRedirect("./login.html");
        }
    }
}

3、页面展示

登录:
在这里插入图片描述

主页:
在这里插入图片描述

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

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

相关文章

【消息中间件】kafka高性能设计之内存池

文章目录 前言实现创建内存池分配内存释放内存 总结 前言 Kafka的内存池是一个用于管理内存分配的缓存区域。它通过在内存上保留一块固定大小的内存池&#xff0c;用于分配消息缓存、批处理缓存等对象&#xff0c;以减少频繁调用内存分配函数的开销。 Kafka内存池的实现利用了…

怎么在本地运行umi框架的生产模式

怎么在本地运行umi框架的生产模式 第一种 先使用build进行编译构建, 在webstorm软件上可以在package.json文件上点击运行;或者直接在命令行上敲max build进行构建, 构建好后就会多个dist目录&#xff0c;里面就是编译好的静态文件。 然后在package.json中添加 "serve&qu…

UDP通信机制详解

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

Helm常用命令记录

问: 到哪里去搜索helm package? 答: artifacthub.io helm versionhelm repo add bitnami https://charts.bitnami.com/bitnamihelm install my-release bitnmai/mysqlkubectl get po --all-namespaceshelm uninstall my-release 安装monitoring,推荐kube-prometheus-stack&am…

【SWAT水文模型】SWAT水文模型建立及应用第三期:基于世界土壤数据库HWSD建立土壤库

SWAT水文模型建立及应用&#xff1a;土壤库建立 1 简介2 土壤数据下载2.1 数据下载方式2.1.1 世界土壤数据库HWSD数据2.1.2 中国土壤数据库 2.2 数据下载 3 土壤数据的准备3.1 SWAT土壤数据库参数3.2 提取HWSD中土壤参数3.3 土壤类型分布图的处理3.4 土壤质地转化3.5 土壤参数的…

人工智能浪潮中,AI如何为企业降本增效?

人工智能浪潮下&#xff0c;企业应如何抓住机遇&#xff0c;用AI降本增效&#xff1f;如何选择适合自身产业的人工智能服务&#xff1f;如果你想了解更多&#xff0c;本文或许能给你提供一点思路。 一、企业如何利用AI降本增效 在人工智能浪潮下&#xff0c;已有多款AI产品问世…

京东APP百亿级商品与车关系数据检索实践 | 京东云技术团队

导读 本文主要讲解了京东百亿级商品车型适配数据存储结构设计以及怎样实现适配接口的高性能查询。通过京东百亿级数据缓存架构设计实践案例&#xff0c;简单剖析了jimdb的位图(bitmap)函数和lua脚本应用在高性能场景。希望通过本文&#xff0c;读者可以对缓存的内部结构知识有…

一文带你写好:项目说明文档README.md

1、前言 公开项目中&#xff0c;一个好的 README 能帮助我们的公开项目&#xff0c;在 GitHub 上的众多项目和开发人员中脱颖而出&#xff1b;商业项目中&#xff0c;一个好的 README 能帮助部门同事更好理解用途和项目进展。下面我们一起讨论什么是 README 自述文件以及如何编…

如何使用node发布自己的包

一、新建文件夹 gzmTestNode二、npm init {"name": "gzmTestNode","version": "1.0.0","description": "处理不同日期函数组件","main": "index.js","scripts": {"test&quo…

从爆火的“哇呀挖”,思考我软件开发的人生意义何在?

【 在什么样的花园里面&#xff0c;挖呀挖呀挖&#xff0c;种什么样的种子&#xff0c;开什么样的花&#xff0c;在小小的花园里面&#xff0c;挖呀挖呀挖&#xff0c;种小小的种子&#xff0c;开小小的花&#xff0c;在大大的花园里面&#xff0c;挖呀挖呀挖&#xff0c;种大大…

springboot+vue火车订票管理系统(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的火车订票管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风…

String [中]

目录 一、 string 的深浅拷贝 0x00 构造函数与析构函数的实现 0x01 拷贝构造 0x02 赋值 0x03 整体代码 二、 string的实现 0x01 引入 0x02 c_str 0x03 默认构造函数 三、size()与operator[]的实现 0x01 size()的实现 0x02 operator[]的实现 0x03 遍历实现 四、迭代器…

同步任务、异步任务、宏任务、微任务、任务的执行过程实例详解、setTimeout()是同步还是异步

一、前言 JavaScript是单线程语言&#xff0c;也就是说&#xff0c;只有一条通道&#xff0c;且js中任务是按顺序依次执行的&#xff0c;但若有一个任务时间过长&#xff0c;就会让后续任务一直等待。为了解决这个问题&#xff0c;将任务分为同步任务和异步任务&#xff0c;异…

文案把卖点被埋没?如此挖掘电商产品卖点,让你轻松获客

绝大部分电商卖家开店面临的最大问题就是不知道如何写文案&#xff0c;直接复制品牌的文案容易被告Q权&#xff0c;自己写的又不吸引人&#xff0c;复制竞争对手的更是无法脱颖而出。同时你也不知道这个文案到底好不好&#xff0c;在别人那里可行的文案&#xff0c;可能你就完全…

CTF-PHP反序列化漏洞3-构造POP链

作者&#xff1a;Eason_LYC 悲观者预言失败&#xff0c;十言九中。 乐观者创造奇迹&#xff0c;一次即可。 一个人的价值&#xff0c;在于他所拥有的。可以不学无术&#xff0c;但不能一无所有&#xff01; 技术领域&#xff1a;WEB安全、网络攻防 关注WEB安全、网络攻防。我的…

宽表 VS 多表关联,谁才是大数据分析的最佳选择?

各位数据的朋友&#xff0c;大家好&#xff0c;我是老周道数据&#xff0c;和你一起&#xff0c;用常人思维数据分析&#xff0c;通过数据讲故事。 前段时间和一个客户就数据中台搭建的一些问题进行了交流&#xff0c;其中讨论最多的是到底是用宽表来实现业务需求&#xff0c;…

Lecture 13(Preparation):Network Compression

目录 Network Pruning Knowledge Distillation Parameter Quantization Architecture Design Dynamic Computation 下面介绍五个network compression的技术。这五个技术都是以软体为导向的&#xff0c;在软体上面对network进行压缩&#xff0c;不考虑硬体加速部分。 Netwo…

springboot+vue校园宿舍管理系统

项目简介 分享一个SpringBootvue所做的一个项目&#xff0c;有需要的私信 1.项目描述 访问地址 http://localhost:8088/login.html?redirect_urlhttp://localhost:8087/myproject 超级管理员账户 账户名&#xff1a;admin 密码&#xff1a;123456 系统管理员账户 账户名…

【系统集成项目管理工程师】计算题专题一

一、决策树和期望货币值 1、项目经理向客户推荐了四种供应商选择方案。每个方案损益值已标在下面的决策树上。根据预期收益值&#xff0c;应选择设备供应商 A.供应商1B.供应商2C.供应商3D.供应商4 解题&#xff1a; 供应商 1&#xff1a;60% * 10000 &#xff08;-30000&am…

DDR基础

欢迎关注我的博客网站nr-linux.com&#xff0c;图片清晰度和&#xff0c;排版会更好些&#xff0c;文章优先更新至博客站。 DDR全称Double Data Rate Synchronous Dynamic Random Access Memory&#xff0c;是当代处理器必不可少的存储器件之一。本文关于DDR介绍的核心点如下&…