表白墙完善(数据库,前端,后端Servlet),再谈Cookie和Session。以及一个关于Cookie的练习小程序

目录

表白墙引入数据库 

再谈Cookie和session

得到Cookie

​编辑

设置Cooie

使用Cookie编写一个登入的小界面


表白墙引入数据库 

1.先引入数据库的依赖(驱动包),5.1.49

pom.xml中,在之前的两个之前,再去添加一个

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version>
</dependency>

2.创建本地的数据库

create table messageWall(`from` varchar(20),`to` varchar(20),message varchar(1024));

3.之前的代码中有一段可以删掉了

 //此处把消息保存到内存中(一旦重启服务器,内存数据就会消失了。更科学的做法,应该是保存到数据库里面)private List<Message> messageList=new ArrayList<>();

这个代码需要删除,因为我们已经决定使用数据库去存储了,就不需要本地去存了。

 完整代码

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;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.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;class  Message{public String from;public String to;public String message;@Overridepublic String toString() {return "Message{" +"from='" + from + '\'' +", to='" + to + '\'' +", message='" + message + '\'' +'}';}
}@WebServlet("/message")
public class MessageServlet extends HttpServlet {//首先要把一个json转化为java对象private ObjectMapper objectMapper=new ObjectMapper();//此处把消息保存到内存中(一旦重启服务器,内存数据就会消失了。更科学的做法,应该是保存到数据库里面)private List<Message> messageList=new ArrayList<>();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.需要能够读取请求body,转换成java对象Message message=objectMapper.readValue(req.getInputStream(),Message.class);//2.得到message之后,需要把message保存到服务器中try {save(message);} catch (SQLException e) {e.printStackTrace();}System.out.println("服务器收到message:"+message.toString());//3.返回响应,(其实没啥大必要,主要是返回一个200ok就行,body可以没有)resp.setStatus(200);                          //设置成功状态码,会更加清晰resp.getWriter().write("ok");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {List<Message>messageList= null;try {messageList = load();} catch (SQLException e) {e.printStackTrace();}//1.把内存中的这些Message,组织成json格式,返回到响应中String respJson=objectMapper.writeValueAsString(messageList);//这个代码十分关键,告诉浏览器,返回的响应的body是json格式(utf8编码)resp.setContentType("application/json; charset=utf8");resp.getWriter().write(respJson);// 2.针对List/数组这种,jackon会自动把数据整理成json数组,里面每个对象,又会被jsckon转换成{}json对象(json对象属性名字,也是和Message类的成员名字对应的)}private void save(Message message) throws SQLException {//通过jdbc从数据库中存储数据。DataSource dataSource=new MysqlDataSource();//useSSL=false 此处的SSL就是HTTPS中的加密方案((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/message?characterEncoding=utf8&&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("lcl15604007179");//2.建立链接Connection connection=dataSource.getConnection();//3.构造SQLString sql="insert into messageWall values(?,?,?)";PreparedStatement statement=connection.prepareStatement(sql);statement.setString(1, message.from);statement.setString(2, message.from);statement.setString(3, message.from);//4.执行SQLstatement.executeUpdate();//5.释放资源,关闭连接statement.close();connection.close();}private List<Message> load() throws SQLException {//通过jdbc,从数据库读取数据//1。创建数据源DataSource dataSource=new MysqlDataSource();((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/message?characterEncoding=utf8&&useSSL=false");((MysqlDataSource) dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("lcl15604007179");//2.建立连接Connection connection= dataSource.getConnection();//3.构造SQLString sql="select *from messageWall";PreparedStatement statement=connection.prepareStatement(sql);//4.执行SQLResultSet resultSet= statement.executeQuery();//5.遍历结果集合List <Message> messageList=new ArrayList<>();while (resultSet.next()){Message message=new Message();message.from=resultSet.getString("from");message.to=resultSet.getString("to");message.message=resultSet.getString("message");messageList.add(message);}//关闭连接,释放资源resultSet.close();statement.close();connection.close();return messageList;}}

我们可以知道,表白墙上的东西,即使你关闭服务器,我们的数据也是保存的,这也是游戏停服了但是你的数据不丢失的原因。

再谈Cookie和session

Cookie是浏览器在本地持久化存储数据的一种机制

1.Cookie的数据从哪里来?

服务器返回给浏览器的

2.Cookie的数据长什么样子?

Cookie中是键值对结构的数据,并且这里的键值对都是程序员自定义的。

3.Cookie有什么用

Cookie可以在浏览器这边存储一些临时性数据

其中最典型的一种使用方式,就是用来存储“身份标识”

sessionId->Cookie和Session之间的联动了

4.Cookie到哪里去

Cookie的内容会在下次访问该网站的时候,自动被带到HTTP请求中

5.Cookie怎么存储的

浏览器按照不同的域名分别存储Cookie域名和域名之间不能打扰。

Cookie存储在硬盘上的

Cookie存储往往会有一个超时时间(看浏览器不同而定,支付宝很短,安全)

得到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("/getcookie")
public class GetCookieServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Cookie[] cookies = req.getCookies();if (cookies != null) {for (Cookie cookie : cookies) {System.out.println(cookie.getName() + ":" + cookie.getValue());}} else {resp.getWriter().write("当前请求中没有cookie");}resp.getWriter().write("ok");}
}

设置Cooie

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("/setcookie")
public class SetCookieServlet extends HttpServlet {//期望通过doGet方法,把一个自定义的cookie数据返回到浏览器这边。@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Cookie cookie=new Cookie("date","2023-09-23");resp.addCookie(cookie);Cookie cookie1=new Cookie("time","19:55");resp.addCookie(cookie1);resp.getWriter().write("setCookie ok");}
}

我们需要是先设置Cookie之后,就可以此时拿到Cookie的内容,当然Cookie里面的数据,只是在浏览器休息休息,真正发挥作用,还是得在服务器这边的逻辑生效的。

Cookie结合Session实现登入效果,此时就能更清楚的看出来

sessionId是一个广义的概念,不同的库中具体实现过程会有一些细节的差异,在Servlet里,把这个属性具体叫做JSESSIONID

getSession背后做的事情(会话,就相当于账户,用户和服务器的交流,之前有没有这个账户)

1.读取请求中的Cookie,看Cookie里面是否有JESSIONID属性,以及值是什么,如果没有,就认为需要创建新的会话,如果有,就拿着这个ID去查询当前的session是否存在

要是session存在,就直接返回该session

要是session不存在,就准备创建新的会话。

2.如果当前确实需要创建会话,就会创建一个Session对象,同时生成唯一的一个JESSIONID,以JSESSIONID为key,SESSION对象为value,把这个键值对插入到服务器上述的哈希表中

3.刚才生成的JESSIONID又会通过addCookie方法,加入到响应中,此时响应里就会带有Set-Cookie字段,这里的值就是JSEEION=xxxxxxx通过响应,就把JSESSIOID返回到浏览器这边了。

这一行小小的,能量大大的🙉🙉🙉

 HttpSession session=req.getSession(true);

问题1:什么情况会有sessionId但是没有session呢

服务器这边存的session对象也是在内存中进行的

比如把sessionId返回给浏览器了,sessionId和session对象是保存在服务器内存的,此时如果服务器重启了,内存中这些会话数据就没了,但是浏览器中的Cookie还是存在的

session存在内存中不太合理,实践中往往会把这种会话保存到其他介质上,来达到持久化存储目的(mysql,redis)

使用Cookie编写一个登入的小界面

简单的一个小的前端代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<form action="login" method="post"><input type="text" name="username"><input type="password" name="password"><input type="submit"  value="登入">
<!--  当前页面是一个form表单--></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("/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;}//已经登入成功了//就可以取出之前的attributeString username=(String) session.getAttribute("username");Long time=(Long) session.getAttribute("time");System.out.println("username="+username+",time"+time);//根据这样的内容构造页面resp.setContentType("text/html;charset=utf8");resp.getWriter().write("欢迎您,"+username+"!上次登入时间"+time);}
}

重定向的内容编写 

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 {//1.获取到用户名和密码String username = req.getParameter("username");String password = req.getParameter("password");if (username == null || password == null || username.equals("") || password.equals("")) {resp.setContentType("text/html;charset=utf8");resp.getWriter().write("请求的参数不完整");return;}//2.验证用户密码是否正确//正常的验证,是从数据库读取数据//注册账号就会给数据库插入用户名和密码,登入的时候就是验证当前用户名是否存在,以及密码是否匹配//当前为了简单,先不引入数据库,直接通过硬编码的方式来判定用户名和密码//此处约定,合法的用户名是:zhangsan,密码:123if (!username.equals("zhangsan")) {resp.setContentType("text/html;charset=utf8");resp.getWriter().write("用户名错误!");return;}if (!password.equals("123")) {resp.setContentType("text/html;charset=utf8");resp.getWriter().write("密码错误");return;}//3.登入成功了,此时可以给这个用户创建会话(就是这个人在不在账户上)HttpSession session = req.getSession(true);//会话总,可以顺便保存点自定义的数据,比如保存一个登入的时间戳//setAttribute后面的value是个Object,想要存什么都可以!!session.setAttribute("username", username);session.setAttribute("time", System.currentTimeMillis());//4.让页面自动跳转到网站主页//此处约定的路径是index(使用Servlet生成一个动态页面)resp.sendRedirect("index");}
}

当前程序设计三个部分进行联动——以下是登入成功的效果

1.登入界面(静态的html,使用form构造http请求)

2.LoginServlet(doPost处理登入的逻辑流程 1234)

3.IndexServlet(doGet处理主页的生成)

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

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

相关文章

【Windows 开发环境配置——NVIDIA 篇】CUDA、cuDNN、TensorRT 三件套安装

CUDA 从CUDA Toolkit Archive下载相应版本的离线安装包&#xff0c;这里以11.7为例。 打开安装包&#xff0c;在安装选项选择自定义模式&#xff0c;点击下一步。 在自定义安装选项中&#xff0c;仅选择CUDA组件&#xff08;其中Nsight相关组件用于代码调试与性能分析&#xff…

HarmonyOS分布式文件系统开发指导

分布式文件系统概述 分布式文件系统&#xff08;hmdfs&#xff0c;HarmonyOS Distributed File System&#xff09;提供跨设备的文件访问能力&#xff0c;适用于如下场景&#xff1a; 两台设备组网&#xff0c;用户可以利用一台设备上的编辑软件编辑另外一台设备上的文档。平板…

CKA认证模块②-K8S企业运维和落地实战-2

CKA认证模块②-K8S企业运维和落地实战-2 K8S常见的存储方案及具体应用场景分析 k8s存储-empty emptyDir类型的Volume是在Pod分配到Node上时被创建&#xff0c;Kubernetes会在Node上自动分配一个目录&#xff0c;因此无需指定宿主机Node上对应的目录文件。 这个目录的初始内容…

计算机网络之网络体系结构

计算机网络体系结构 一、常见的计算机体系结构 1.1 OSI标准以及TCP/IP体系结构 OSI标准失败的原因&#xff1a; OSI的专家们缺乏实际经验&#xff0c;他们在完成OSI标准时没有商业驱动力OSI的协议实现起来过分复杂&#xff0c;而且运行效率很低OSI标准的制定周期太长&#x…

css:文本对齐属性vertical-align实现化学元素上标下标的显示

文档 https://developer.mozilla.org/zh-CN/docs/Web/CSS/vertical-align 语法 vertical-align: <value>;可选值&#xff1a; sub&#xff1a;使元素的基线与父元素的下标基线对齐。 super&#xff1a;使元素的基线与父元素的上标基线对齐。 text-top&#xff1a;使…

JAVA 中集合取交集

日常工作 经常需要取两个数据集的交集。对常用的List 和Set集合做了一个测试 public static void main(String[] args) {List<Integer> list1 Lists.newArrayList();List<Integer> list2 Lists.newArrayList();Set<Integer> set3 Sets.newHashSet();Set&l…

基于SSM的药店药品销售系统

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

程序员的护城河

程序员的护城河是一个多维度的概念&#xff0c;它包括技术能力的深度、对创新的追求、沟通协作等软实力。这些因素共同构成了程序员在保障系统安全、数据防护以及网络稳定方面所起到的重要作用。 首先&#xff0c;技术能力的深度是程序员的核心竞争力之一。随着科技的不断发展…

车载通信与DDS标准解读系列(1):DDS-RPC

▎RPC & DDS-RPC RPC&#xff1a;Remote Procedure Call&#xff0c;远程过程调用。 远程过程调用是一种进程间通信&#xff0c;它允许计算机程序在另一个地址空间中执行子程序&#xff0c;就好像用别人的东西像用自己的一样&#xff0c;常用于分布式系统。 远程过程调用…

3分钟带你了解前端缓存-HTTP缓存

前情提要 前端缓存分为下面三大类&#xff0c;本文主要讲解HTTP缓存~ 1. HTTP缓存 强缓存协商缓存 2. 浏览器缓存 本地小容量缓存本地大容量缓存 3. 应用程序缓存 HTML5应用程序缓存 缓存作用 减少了冗余的数据传输减少服务器的负担提高了网站的性能加快加载网页速度 …

易基因:综合全基因组DNA甲基化和转录组学分析鉴定调控骨骼肌发育潜在基因 | 研究进展

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 DNA甲基化是骨骼肌发育中关键的表观遗传调控机制。但胚胎鸭骨骼肌发育中负责DNA甲基化的调控因子仍然未知。 2023年10月23日&#xff0c;南京农业大学动物科技学院于敏莉副教授团队在《…

核心!华为自研系统鸿蒙趋势

鸿蒙系统的推出引起了全球的关注&#xff0c;毕竟这是华为自主研发的操作系统。这个系统有一些特点很独特。首先&#xff0c;它的自主可控性是一大特色。因为是自家研发的&#xff0c;所以更容易适应外界变化。其次&#xff0c;它采用了分布式架构&#xff0c;这样不同设备之间…

GitHub Universe 2023:AI 技术引领软件开发创新浪潮

GitHub 是全球领先的软件开发和协作平台&#xff0c;数百万开发者和企业在此分享、学习和创建卓越的软件。同时 GitHub 处在 AI 技术前沿&#xff0c;通过其先进的 AI 技术增强开发者体验并赋能未来软件开发的使命。在今天的文章中&#xff0c;我们将一起看看在 GitHub 年度大会…

project打开文件时,显示无法识别此文件格式?

环境&#xff1a; Win 10 专业版 project 2021 问题描述&#xff1a; project打开文件时&#xff0c;显示无法识别此文件格式&#xff1f; 解决方案&#xff1a; 1.测试新建文件&#xff0c;打开都是这样&#xff0c;检查文件都不是旧版本创建&#xff08;未解决&#xff…

Linux之输入输出重定向和管道

一、是什么 linux中有三种标准输入输出&#xff0c;分别是STDIN&#xff0c;STDOUT&#xff0c;STDERR&#xff0c;对应的数字是0、1、2&#xff1a; STDIN 是标准输入&#xff0c;默认从键盘读取信息STDOUT 是标准输出&#xff0c;默认将输出结果输出至终端STDERR 是标准错误…

做作业用台灯好还是不用台灯?高口碑护眼台灯分享

相信大家在生活着也遇到过这个问题&#xff0c;就是孩子在写作业时需不需要使用台灯。有些家长可能认为家里室内的亮度已经很足了&#xff0c;没必要使用台灯。 其实这个想法是错误的&#xff0c;孩子在书写作业时是需要使用台灯的&#xff01;室内灯源照到书桌时时远远不够的&…

jupyter lab配置列表清单

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

数据结构上机实验——图的实现(以无向邻接表为例)、图的深度优先搜索(DFS)、图的广度优先搜索(BFS)

文章目录 数据结构上机实验1.要求2.图的实现&#xff08;以无向邻接表为例&#xff09;2.1创建图2.1.1定义图的顶点、边及类定义2.1.2创建无向图和查找2.1.3插入边2.1.4打印函数 2.2图的深度优先搜索&#xff08;DFS&#xff09;2.3图的广度优先搜索&#xff08;BFS&#xff09…

竞赛 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题

文章目录 1 前言2 垃圾短信/邮件 分类算法 原理2.1 常用的分类器 - 贝叶斯分类器 3 数据集介绍4 数据预处理5 特征提取6 训练分类器7 综合测试结果8 其他模型方法9 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器学习的垃圾邮件分类 该项目…

技术贴 | SQL 执行 - 执行器优化

本期技术贴主要介绍查询执行引擎的优化。查询执行引擎负责将 SQL 优化器生成的执行计划进行解释&#xff0c;通过任务调度执行从存储引擎里面把数据读取出来&#xff0c;计算出结果集&#xff0c;然后返回给客户。 在关系型数据库发展的早期&#xff0c;受制于计算机 IO 能力的…