cookie机制 + java 案例

目录

为什么会有cookie??

cookie从哪里来的??

cookie到哪里去??

cookie有啥用??

 session

HttpServletRequest类中的相关方法

简单的实现cookie登录功能

实现登录页面

实现servlet逻辑

实现生成主页

 部署tomcat服务器

访问登录页面

问题 


创作不易多多支持


为什么会有cookie??

        cookie是浏览器在本地存储数据的一种机制首先我们的数据很多都是存放在服务器上的,但是服务端也想这能不能在客户端也存放一些数据。但是又要保证本地的安全,不能让浏览器直接控制本地的存储设备,所以就做了一个中立的做法,也就是说让浏览器开一个口子,使用某些特殊的键值对,来限定数据的存储保证安全,同时又可以让浏览器往本地存储数据。

cookie从哪里来的??

        cookie是从服务器来的。服务器在响应中会带有Set-Cookie字段,通过这个字段就可以把要保存在浏览器本地的数据给返回回去。

cookie到哪里去??

        后续浏览器访问服务器的时候,就会把当前本地的所有cookie都通过http带给服务端

cookie有啥用??

        最典型的场景就是使用cookie保存当前用户的登录状态。就例如我们经常访问b站的时候,只登录了一次,后面关闭页面再次打开,任然保持这上次的登录状态。

        在cookie保存用户身份标识,这样的应用场景之中,此时身份标识该如何分配,以及身份信息该如何存储,都是需要服务器的支持的。这个就要利用一个session会话机制。

 session

        session给当前用户分配一个sessionId。同时记录下当前用户的身份信息(可以自定义的),这个id就会被返回到浏览器的cookie中,后续浏览器访问服务器都会带着这个。从而能让服务器识别到当前用户的身份。

下面我们结合代码,来了解一下cookie的机制。

HttpServletRequest类中的相关方法

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

        下面我们来解析一下这个getSession的用法,首先getSession的参数如果为false,那么就会触发以下流程:

  1. 读取cookie中的sessionid
  2. 然后再服务器这边根据服务器存储的数据和sessionid一起,查询Session对象
  3. 如果查到了就会直接返回这个session对象
  4. 否则返回null

        如果为true的话,与false唯一不同就只有第四步不一样,如下:

  1. 读取cookie中的sessionid
  2. 然后再服务器这边根据服务器存储的数据和sessionid一起,查询Session对象
  3. 如果查到了就会直接返回这个session对象
  4. 否则返回创建一个新的session对象,同时生成一个sessionid,同时以sessionid为key ,以session对象为value构成一个键值对,然后把这个键值对存储到服务器的hash表里面
  5. 同时把sessionid以setcookie 的方式返回给浏览器 

        这个对我们实现登录功能非常实用。

简单的实现cookie登录功能

         接下来我们基于httpServlet来实现一个简单的登录功能。

        首先需要提供两个页面:

  1. 登录页(输入用户id,输入密码,然后还有一个登录按钮,点击登录就会发起一个http请求,服务器就会处理这个http请求,服务器处理这个请求的时候就会验证用户名和密码,如果用户名和密码都ok,就会跳转主页)
  2. 主页(不存在任何业务逻辑,仅仅只是展示一个欢迎页面)

        其中的登陆页面就只是单纯的html页面,还需要写一个servlet,实现登录的时候用户名密码校验,还要写一个servlet来生成主页

实现登录页面

        首先先来回忆一下我们传输键值对的方式,一说到传输键值对,那么肯定就要提到html里面的form表单

    <form action="login" method="post">
        <input type="text" name="username"> <!--用户输入的用户名-->
        <br>
        <input type="password" name="password">  <!--用户输入的密码-->
        <br>
        <input type="submit" value="登录">
    </form>

        form会组织这里的数据,以键值对的形式提交给服务器,其中key就是input的name属性,value就是input中用户输入的内容,最终会构造post请求,在body中以键值对的形式,进行组织。服务器通过getParameter方法来获取指定key的value,具体getParameter的方法可以参看我前面的servelet的内容。

        完整的登录页面的代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="login" method="post">
        <input type="text" name="username"> <!--用户输入的用户名-->
        <br>
        <input type="password" name="password">  <!--用户输入的密码-->
        <br>
        <input type="submit" value="登录">
    </form>
</body>
</html>

实现servlet逻辑

         新建一个类,为loginServlet类来处理上述的登录请求。

        登录的请求形式如下:

  • POST/login
  • Content-Type:application/x-www-form-urlencoded
  • username=zhangshan&password=1233

         一般像登录这样的请求都是post

构造好的登录的处理逻辑如下:

package Login;

import javax.jws.WebService;
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 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.setContentType("text/html;charset=utf8");
        // 首先通过getParameter方法来获取对应key的value值
        String username = req.getParameter("name");
        String password = req.getParameter(("password"));
        // 然后来验证这个用户和密码是否正确
        if (username == null || password == null || username.equals("") || password.equals("")){
            resp.getWriter().write("当前用户名和密码不能为空");
            return;
        }
        // 假设此处的密码和用户名只能是zhangsan和1234
        // 逻辑上此处应该是在服务器的数据库里面去查找验证用户名和密码,此处简化步骤
        if (username.equals("zhangsan") || username.equals("lisi")) {
            if (password.equals("1234")) {
                // 此时用户输入密码正确
            } else {
                // 用户密码有误
                resp.getWriter().write();
            }
        } else {
            // 用户名错误
        }
    }
}

这是简单的登录逻辑。

        接下来,如果登录的用户名和密码验证正确的话,就会触发session会话,如下:

        // 此时用户属于未登录的状态,所以请求的cookie中没有sessionid,所以无法从服务器的hash表中获取到对应的session对象
        // 所以此处吧getSession中的参数设置为true,(在查询不到的时候创建新的sesion会话和session对象并存储到hash表中)
        // 同时会返回这个session对象,并且接下来会将新的sessionid通过响应http返回给客户端浏览器。
        HttpSession session = req.getSession(true);

        // 然后让刚刚创建好的session对象存储我们自定义的数据,就可以在这个对象中存储用户的身份信息
        session.setAttribute("username",username);

        session对象本身就可以看作一个hash表,通过setAttribute方法来存储键值对(setAttribute方法里面有两个参数,一个是String(key),一个是Object(value)),后续就可以通过getAttribute根据key来获取value。

        最后登录成功之后跳转到主页:

// 登录成功之后 需要自动跳转到 主页欢迎页
        resp.sendRedirect("index");

        下面是loginServlet的代码:

package Login;

import javax.jws.WebService;
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.setContentType("text/html;charset=utf8");
        // 首先通过getParameter方法来获取对应key的value值
        String username = req.getParameter("name");
        String password = req.getParameter(("password"));
        // 然后来验证这个用户和密码是否正确
        if (username == null || password == null || username.equals("") || password.equals("")){
            resp.getWriter().write("当前用户名和密码不能为空");
            return;
        }
        // 假设此处的密码和用户名只能是zhangsan和1234
        // 逻辑上此处应该是在服务器的数据库里面去查找验证用户名和密码,此处简化步骤
        if (username.equals("zhangsan") || username.equals("lisi")) {
            if (password.equals("1234")) {
                // 此时用户输入密码正确
            } else {
                // 用户密码有误
                resp.getWriter().write();
            }
        } else {
            // 用户名错误
        }
        // 此时用户属于未登录的状态,所以请求的cookie中没有sessionid,所以无法从服务器的hash表中获取到对应的session对象
        // 所以此处吧getSession中的参数设置为true,(在查询不到的时候创建新的sesion会话和session对象并存储到hash表中)
        // 同时会返回这个session对象,并且接下来会将新的sessionid通过响应http返回给客户端浏览器。
        HttpSession session = req.getSession(true);

        // 然后让刚刚创建好的session对象存储我们自定义的数据,就可以在这个对象中存储用户的身份信息
        session.setAttribute("username",username);

        // 登录成功之后 需要自动跳转到 主页欢迎页
        resp.sendRedirect("index");
    }
}

实现生成主页

         首先需要验证身份信息:

HttpSession session = req.getSession(false);
        if (session == null ) {
            // 当前是未登录状态
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("当前用户未登录");
            return;
        }

        此处的查询到的sessiom对象应该是和刚才登录的session对象是同一个对象,因为是同一个sessionid。刚才登录成功,sessionid就会通过Set-Cookie返回给浏览器,浏览器下次访问IndexServlet的时候,就会带上这个同一个sessionid。

package Login;

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 {
        // 此处禁止创建新的会话,如果没有找到,那么就认为此用户为未登录状态
        // 如果找到了才认为是登录状态
        HttpSession session = req.getSession(false);
        if (session == null ) {
            // 当前是未登录状态
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("当前用户未登录");
            return;
        }
        String username = (String)session.getAttribute("username");
        // 在服务器这边维护了一个全局的hash表,key就是sessionid,value就是session对象
        if (username == null) {
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("当前用户未登录");
            return;
        }
        // 如果都ok就生成动态主页
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("欢迎你!!"+ username);
    }
}

 部署tomcat服务器

         选择edit configuration:

        添加smart tomcat选项:

         设置端口8080(默认),重新命名,然后启动:

访问登录页面

        访问: http//127.0.0.1:8080/login/login.html

        输入“zhangsan”,1234

         就会收到浏览器请求保存cookie的请求。点击明白即可,我们点击编辑可以查看到我们的用户名和密码都已经保存到本地了。

        下面使用费德勒来抓包看看我们信息传递的过程,如下:

        输入用户名和密码之后就会构造一个http请求访问login的页面,随后访问index页面 

         抓包的结果可以看出来,第一次访问的时候是没有cookie的,后面setCookie之后就有了。

        第二次请求index的请求如下:

        可以看到最后的存在一个Cookie字段 

          

        下次无论你怎么刷新,都是显示“欢迎你!!zhangsan” 。

问题 

        上面的sessionid也不一定会一直存在,比如说服务器重新启动,session的hash表就会清除,此时如果再访问就可能出现sessionid无法查询到,此时还是未登录状态,需要重新登录。

        服务器默认保存会话是再内存中的,一但重启服务器会话服务就会销毁,但是smart tomcat为了方便程序员方便调试程序,会在停止服务器的时候,把会话持久化保存,下次启动的时候自动恢复到内存中,这个时候会话还是不会丢失的(这个时候真的有效,跟tomcat版本有关)。 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

牛客机考题编程题输入输出

有时空可以练练这里的题目&#xff1a; https://ac.nowcoder.com/acm/contest/5652 做个总结&#xff0c;其实就两种输入类型&#xff1a; 一种是下面这种&#xff0c;需要对输入的每行进行运算 这种就是循环读取每行的数做一个运算&#xff1a; import sys while True:line …

【Nuxt】Nuxt3 动态导入图片 src

nuxt3 不再支持 require 动态导入资源&#xff0c;因此需要我们将图片放到 public 目录下&#xff0c;这样我们就可以动态导入了 比如下面 &#x1f447;&#xff1a; 感谢 Nuxt3遇见的坑&#xff08;四&#xff09;&#xff1a;图片动态渲染之后打包路径问题以及打包css样式…

代码混淆的原理是什么?常见代码混淆方法介绍

​ 代码混淆的原理是什么&#xff1f;常见代码混淆方法介绍 本文主要想你介绍代码混淆的原理&#xff0c;常见代码混淆方法&#xff0c;欢迎查阅~ 移动应用代码安全非常重要&#xff0c;代码逆向会导致代码逻辑被获取&#xff0c;进一步导致控制流被hook&#xff0c;安全防线被…

SystemVerilog学习 (11)——覆盖率

目录 一、概述 二、覆盖率的种类 1、概述 2、分类 三、代码覆盖率 四、功能覆盖率 五、从功能描述到覆盖率 一、概述 “验证如果没有量化&#xff0c;那么就意味着没有尽头。” 伴随着复杂SoC系统的验证难度系数成倍增加&#xff0c;无论是定向测试还是随机测试&#xff…

reids面试题

1 redis是单线程吗&#xff1f; Redis是单线程 主要是指Redis的网络10和键值对读写是由一个线程来完成的&#xff0c;Redis在处理客户端的请求时包括获取(socket 读)、解析、执行、内容返回(socket 写) 等都由一个顺序串行的主线程处理&#xff0c; 但Redis的其他功能&#xff…

结合 Django 和 Vue.js 打造现代 Web 应用

概要 在 Web 开发的世界里&#xff0c;Django 和 Vue.js 分别是后端和前端两个非常流行的框架。Django 以其强大的后端能力、快速开发以及安全性而著称&#xff0c;而 Vue.js 因其简洁、灵活和易于上手在前端开发领域广受欢迎。 本篇文章将详细介绍如何将 Django 与 Vue.js 结…

Jetson简介、编程开发与环境搭建

Jetson简介、编程开发与环境搭建 简介常用指令Jetpack环境搭建 简介 Jetson是由NVIDIA推出的一系列嵌入式系统&#xff0c;旨在用于机器学习和人工智能应用的开发。Jetson平台通常使用NVIDIA的GPU加速技术&#xff0c;以提供高性能的计算能力。NVIDIA推出了多个Jetson系列的产…

成集云 | 企业微信集成用友T+ | 解决方案

源系统成集云目标系统 方案介绍 用友T是一款由用友畅捷通推出的新型互联网企业管理系统&#xff0c;它主要满足成长型小微企业对其灵活业务流程的管控需求&#xff0c;并重点解决往来业务管理、订单跟踪、资金、库存等管理难题。 企业微信是一款通讯与办公工具&#xff0c;具…

NJU操作系统公开课笔记(1)

目录 一.计算机系统概述 二.计算机硬件系统 三.计算机软件系统 四.计算机操作技术的发展 五.计算机OS 1.资源管理的角度 2. 程序控制的角度 3.OS控制计算机的角度 4.人机交互的角度 5.程序接口的角度 6.系统结构的角度 单道批处理系统 多道批处理系统 分时系统 …

【Git学习二】时光回溯:git reset和git checkout命令详解

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;JavaScript小贴士Git等软件工具技术的使用 &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&a…

链路追踪,助您洞悉数据联动分析的奥秘

前言 在当今复杂的分布式系统中&#xff0c;了解请求在不同服务之间的传递路径和性能情况对于系统的性能优化至关重要。链路追踪通过记录和分析请求在系统中的传递路径和性能数据&#xff0c;为实现数据联动分析提供了重要的支持。我们曾谈论观测云提供火焰图能够实现链路追踪…

开发知识点-前端-webpack

webpack技术笔记 一、 介绍二、 下载使用 一、 介绍 Webpack是一个现代 JavaScript 应用程序的静态模块打包器 打包&#xff1a;可以把js、css等资源按模块的方式进行处理然后再统一打包输出 静态&#xff1a;最终产出的静态资源都可以直接部署到静态资源服务器上进行使用 模…

mysql之rsync远程同步

&#xff08;一&#xff09;rsync 1、rsync&#xff1a;是一个开源的快速备份工具&#xff0c;可以在不同主机之间同步整个目录 2、在远程同步中&#xff0c;一个是源端&#xff0c;一个是发起端 &#xff08;1&#xff09;源端负责文件的原始位置&#xff0c;发起端和源端的…

最新随机小姐姐无水印开源版HTML源码

推荐一款高质量的HTML引流源码&#xff0c;适合浏览小姐姐短视频 这款源码具有出色的用户界面设计&#xff0c;给人视觉上的美感 视频播放流畅稳定&#xff0c;给用户带来良好的观影体验 小姐姐们的外貌也非常美丽吸引人 想要浏览精彩的小姐姐短视频&#xff0c;不妨试试这款…

Equifax案例分析与合规性场景实践

在当今数字化时代&#xff0c;数据安全已经成为各个组织和企业亟待解决的问题。尤其是在数据泄露事件不断增多的背景下&#xff0c;保护敏感数据免受非法访问和泄露变得尤为紧迫。为了应对这一挑战&#xff0c;许多组织和企业开始利用密钥管理服务(KMS)来加强其数据安全性&…

易点易动RFID管理系统:年终固定资产盘点的革命

随着现代企业规模的扩大和固定资产数量的增加&#xff0c;年终固定资产盘点成为了一项繁琐而耗时的任务。传统的手工盘点方法不仅效率低下&#xff0c;还容易出现错误和遗漏。为了解决这一难题&#xff0c;易点易动RFID管理系统应运而生。本文将重点介绍易点易动RFID管理系统在…

基于SSM的个人通讯录(有报告)。Javaee项目。

演示视频&#xff1a; 基于SSM的个人通讯录&#xff08;有报告&#xff09;。Javaee项目。 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 项目介绍&#xff1a; 采用M&#xff08;mod…

分享一个字体抽取软件

一、先下载软件。 地址 蓝奏云 密码 bjnr Fontmin-v0.2.0-win64 下载下来直接就是exe文件&#xff0c;直接双击安装即可。 二、打开默认如图显示 三、接下来把你的字体文件拖拽到里面 四、在把你用到这个字体的文字填入到框内 五、最后点击生成。 生成的字体文件只有2k了…

Eclipse切换中文环境

PACK包链接 地址&#xff0c;进入后可以看到不同版本的包。 要选择跟自己Eclipse版本一致的包&#xff0c;比如我的Eclipse启动界面如下&#xff0c;我就要找Helios的包&#xff08; Juno、Indigo、Helios、Kepler这些具体怎么划分的我也不清楚&#xff09;。 在线安装 打…

Oracle OCM考试(史上最详细的介绍,需要19c OCP的证书)

Oracle 19c OCM考试和之前版本的OCM考试差不多&#xff0c;对于考生来说最大的难点是题量大&#xff0c;每场3小时&#xff0c;一共4场&#xff0c;敲键盘敲得手抽筋。姚远老师&#xff08;v:dataace&#xff09;的很多Oracle OCP学员都对19c OCM考试很有兴趣&#xff0c;这里给…