cookie机制

目录

为什么会有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 {@Overrideprotected 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 {@Overrideprotected 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 {@Overrideprotected 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版本有关)。 

 

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

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

相关文章

广州华锐互动:办税服务厅税务登记VR仿真体验让税务办理更加灵活高效

在数字化世界的今天&#xff0c;我们正在见证各种业务过程的转型&#xff0c;而税务办理也不例外。最近&#xff0c;一种全新的交互方式正在改变我们处理税务的方式&#xff1a;虚拟现实&#xff08;VR&#xff09;。 首先&#xff0c;用户需要戴上虚拟现实头显&#xff0c;然后…

linux下安装python3.8(有坑)

1安装包下载 ###直接官网下载linux版本&#xff0c;找到对应的包 https://www.python.org/downloads/source/2安装包解压 tar -zxvf Python-3.8.0.tgz 3编译安装 1&#xff09;设置安装目录&#xff0c;比如在此创建在 /usr/local/python3 &#xff1a; mkdir -p /usr/loca…

Web自动化测试:Unittest单元测试框架!

一、unitest基础写法格式 1.1引用导入 import unittest 并且需要新建一个类&#xff0c;继承unittest class Demo(unittest.TestCase): 1.2格式代码示例 备注&#xff1a; 1.用例的方法名中&#xff0c;要以test开头才能被读取出来 2.用例的读取顺序按照方法名的ASCII码…

1. hadoop环境准备

环境准备 准备三台虚拟机&#xff0c;配置最好是 2C 4G 以上 本文准备三台机器的内网ip分别为 172.17.0.10 172.17.0.11 172.17.0.12本机配置/etc/hosts cat >> /etc/hosts<<EOF 172.17.0.10 hadoop01 172.17.0.11 hadoop02 172.17.0.12 hadoop03 EOF本机设置与…

2023最新最全【虚幻4引擎】下载安装零基础教程

1、创建Epic Games账户 我们先打开浏览器&#xff0c;输入以下网址&#xff1a;unrealengine.com 随后点击【立即开始】 选择许可证类型&#xff0c;此处提供三种选项&#xff0c;分别是【游戏】、【非游戏】以及【私人定制】 第一类许可证适用于游戏和商业互动产品&#xff…

asp.net网上书店管理系统VS开发sqlserver数据库web结构c#编程计算机网页源码项目

一、源码特点 asp.net网上书店管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 asp.net网上书店系统1 二、功能介绍 本系统使用Microsoft Visual Studio 2019为开发工具&#xff0c;SQL Server为…

在win10环境下安装python,配置python环境,执行python脚本

1.安装python 去python官网下载&#xff1a; https://www.python.org/ 这里采用 Python 3.10.8 版本 选择windows 64位 双击安装&#xff1a; 安装这里有两个选项&#xff1a; 1.默认安装直接选Install Now 2.勾选install launcher for all users&#xff08;recommend&a…

Git客户端(TortoiseGit)使用

参考文章&#xff1a; https://www.cnblogs.com/xuwenjin/p/8573603.html 【精选】使用TortoiseGit工具进行开发&#xff08;连接远程仓库进行克隆、拉取、获取、提交、推送、新建/切换/合并分支、解决冲突&#xff09;_tortoisegit连接远程仓库-CSDN博客 tortoise git 拉取…

UE基础篇四:地形基础概念

导语: 视频文档在文末 一、从引擎中导入高度图 高度图是灰度图,并且每个像素有16位的深度,支持这种格式的是.png 和.raw格式 高度图可以自己绘制,或者通过许多网站下载那些复制现实世界地点的图片,许多网站也有免费资源下载 二、草地和石头混合图层 创建一个混合材质,…

单相浪涌保护器和三相浪涌保护器的区别

浪涌保护器&#xff0c;也称为防雷器&#xff0c;是一种为各种电子设备、仪器仪表、通讯线路提供安全防护的电子装置&#xff0c;主要用于限制过电压和泄放电涌电流。浪涌保护器的核心元件是内部的一个非线性元件。根据非线性元件的不同&#xff0c;浪涌保护器可以分为开关型&a…

开启Windows11 PC无线热点功能

1.鼠标右键点开始的&#xff0c;选择"设置"选项 2.点“网络和Internet”&#xff0c;点开移动热点&#xff0c;在属性中填SSID&#xff0c;设置接入的key 3.还可以设置频段2.4GHZ或5.8GHz&#xff0c;默认支持8个终端接入&#xff0c;是不是很方便&#xff1f;&#…

conan 入门指南

conan 新手入门 1 需要注意的事项2 使用 Poco 库的 MD5 哈希计算器2.1 创建源文件2.2 搜索poco conan 库2.3 获取poco/1.9.4的元数据2.4 创建conanfile.txt2.5 安装依赖2.6 创建编译文件2.7 构建和运行程序 3 安装依赖程序4 检查依赖关系5 搜索软件包6 与其他配置一起构建 该篇…