当前位置: 首页 > news >正文

表白墙程序

目录

一、页面代码部分

二、设计程序

二、实现 doPost​编辑

三、实现 doGet

四、前端代码部分

五、使用数据库存储数据


一、页面代码部分

在之前的一篇博客中,已经写过了表白墙的页面代码实现,这里就不再重复了

页面代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>表白墙</title>
</head>
<body><div class="container"><h1>表白墙</h1><p>输入后点击提交,会将信息显示在表格中</p><div class="row"><span>谁:</span><input type="text" class="edit"></div><div class="row" ><span>对谁:</span><input type="text" class="edit"></div><div class="row"><span>说什么:</span><input type="text" class="edit"></div><div class="row"><input type="button" value="提 交" id="submit"></div><script>let submitButton=document.querySelector('#submit');submitButton.onclick=function(){//1.先获取到编辑框的内容let edits=document.querySelectorAll('.edit');//依靠.value来获得其输入框的值let from=edits[0].value;let to=edits[1].value;let message=edits[2].value;console.log(from,to,message);//这里是对用户输入进行合法的校验,看用户输入是否合法if(from==''||to==' '||message==''){return;}//2.根据内容,构造HTML元素(.row里面包含用户输入的话)//createElement:创建一个元素let row=document.createElement('div');row.className='row';row.innerHTML=from+'对'+to+'说:'+message;//3.把这个新的元素添加到DOM树上let container=document.querySelector('.container');container.appendChild(row);//4.清空原来的输入框for(let i=0;i<edits.length;i++){edits[i].value='';}}</script><style>/*去除浏览器默认样式:内边距,外边距,内边框和外边框不会撑大盒子*/*{margin:0;padding: 0;box-sizing: border-box;}/*margin:0 auto :意思是 中央居中*/.container{width: 400px;margin:0 auto;}/*padding:20px auto :h1标签:上下间距20*/h1{text-align:center;padding:20px auto;}p{text-align:center;color:#666;padding: 10px 0;font-size:14px;}/*display:flex:基于弹性布局justify-content:center:水平居中align-items:center:垂直居中*/.row{height:50px ;display: flex;justify-content: center;align-items:center;}/*现在对于span和input的长度进行调整*/span{width:90px;font-size: 20px;}input{width:310px;height: 40px;font-size: 18px;}/*现在处理一下 提交 按钮首先,提交按钮宽度和父元素一样宽其次,设置字体颜色和背景颜色然后,border:none:作用:为了去除黑边框border-radius:设置四个角角为圆矩形font-size:设置 提交 字体的大小*/#submit{width: 400px;color: white;background-color:orange;border:none;border-radius:5px;font-size: 18px;}/*点击 提交 按钮 就会改变其背景颜色*/#submit:active{background-color: black;}</style></div>
</body>
</html>

二、设计程序

之前写的页面有两个非常严重的问题:

1、如果刷新页面 / 关闭页面 重开,之前输入的消息就不见了

2、如果一个机器上输入了数据,第二个机器是看不到的(这些数据都是在本地浏览器中)

解决思路:

让服务器来存储用户提交的数据,由服务器保存

当由新的浏览器打开页面的时候,再从服务器获取数据

此处服务器就可以用来存档和读档的操作

写 web 程序,务必要重点考虑前后端如何交互,也就是约定好前后端交互的数据格式

这个过程,称为 设计前后端交互接口

请求时什么样的,响应是什么样的,浏览器什么时候发送请求,浏览器按照什么格式来解析....

那么哪些环节涉及到前后端交互呢?

1、点击提交,浏览器把表白信息发送到服务器这里

2、页面加载,浏览器从服务器获取到表白信息

1、点击提交,浏览器把表白信息发送到服务器这里

2、页面加载,浏览器从服务器获取到表白信息

此处的约定,没有固定的强制要求,只要保证能够实现必要的需求即可,此处的目的是为了前后端可以对上号

注意:这里的路径得和之前约定的保持一致


二、实现 doPost

我们要先定义一个类,描述请求的 body 内容,方便 jackson 进行 json 解析

class Message{public String from;public String to;public String message;
}

然后使用 List 来存储数据

 //使用 List 变量保存所有消息private List<Message> messagesList = new ArrayList<>();//向服务器提交数据@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ObjectMapper objectMapper = new ObjectMapper();//把 body 中的内容读取出来,解析成 message 对象Message message = objectMapper.readValue(req.getInputStream(),Message.class);//此处,通过一个简单粗暴的方式来完成保存messagesList.add(message);//此处的设定状态码可以省略,不设置,默认也是200resp.setStatus(200);}

doPost 做的事情,就是把解析的 message 往 List 里面添加


三、实现 doGet

另一方面,实现 doGet ,也就是把 List 的结果,返回给前端

响应数据,也是一个 json 数据

基于 objectMapper 的 writeValue 方法,就可以把 List <Message> 转换成 json 格式

这个方法,同时完成了把 java 对象,转换成 json 和把 json 字符串写到响应对象中

第一个参数是 Writer 对象,表示转成的 json 字符串,往哪个地方去写,第二个参数就是当前存储消息的 List ,意思是要把哪个对象转换成 json 

如果分成两步,就是这样写的:

    //从服务器获取数据@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ObjectMapper objectMapper = new ObjectMapper();//显示告诉浏览器,数据是 json 格式,并且字符集是 utf8resp.setContentType("applicaion/json; charseet=utf8");objectMapper.writeValue(resp.getWriter(),messagesList);}

针对 doGet ,只是把 MessageList 给转换成 json 字符串,返回给浏览器

class Message{public String from;public String to;public String message;
}@WebServlet("/message")
public class MessageServlet extends HttpServlet {//使用 List 变量保存所有消息private List<Message> messagesList = new ArrayList<>();//向服务器提交数据@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ObjectMapper objectMapper = new ObjectMapper();//把 body 中的内容读取出来,解析成 message 对象Message message = objectMapper.readValue(req.getInputStream(),Message.class);//此处,通过一个简单粗暴的方式来完成保存messagesList.add(message);//此处的设定状态码可以省略,不设置,默认也是200resp.setStatus(200);}//从服务器获取数据@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ObjectMapper objectMapper = new ObjectMapper();//显示告诉浏览器,数据是 json 格式,并且字符集是 utf8resp.setContentType("applicaion/json; charset=utf8");//objectMapper.writeValue(resp.getWriter(),messagesList);//把 java 对象转换成 json 字符串String jsonResp = objectMapper.writeValueAsString(messagesList);//把字符串写回到响应 body 中resp.getWriter().write(jsonResp);}
}

写到这里,表白墙的后端就大功告成了,我们可以打开 postman 对代码进行测试

当前这只是给前端返回 json 字符串,要想成为键值对,还需要额外的代码


四、前端代码部分

接下来,我们来编写前端代码,也就是让页面能够发起上述请求,并解析响应

post 是点击提交按钮的时候发起,get 是页面加载的时候发起

这个代码是在定义一个 js 对象(类似于 json 的键值对)

key 其实是字符串,value 则是 js 中的变量/常量

js 中要求, 对象中的 key 务必是 字符串,所以这里的 "" 可以省略

当前 body 是个 js 对象,不是字符串,网络传输,只能串字符串,不能传对象

所以,我们需要把目前这个对象转成字符串

js 内置了转换 json 的库

                //4、[新增] 给服务器发起 post 请求,把上述数据提交到服务器let body = {from :from,to:to,message:msg};strBody = JSON.stringify(body);console.log("strBody: " + strBody);$.ajax({type:'post',url:'message',data:strBody, contentType:"application/json;charset=utf8",success:function(body){console,log("数据发布成功");}});

接下来需要实现下 读档操作,让 ajax 发送 GET 请求

            //[新增] 在页面加载的时候,发送 GET 请求,从服务器获取到数据并添加到页面中$.ajax({type:'get',url:'message',success:function(body){//此处拿到的 body 就是一个 js 的对象数组了//本来服务器返回的是一个 json 格式的字符串,但是 jquery 的 ajax 可以自动识别,//自动帮我们把 json 字符串转成 js 对象数组//接下来,遍历这个数组,把元素取出来,并且构造到页面中即可for(let message of body){//针对每个元素构造一个 divlet row=document.createElement('div');row.className='row';row.innerHTML=message.from +'对'+message.to +'说:'+message.message;containerDiv.appendChild(rowDiv);}}});

五、使用数据库存储数据

当前我们的数据是在内存(变量) 中保存的,重启服务器就没了

要想持久化保存,就需要写入文件中(硬盘)

1、直接使用 流对象 写入文本文件

2、借助数据库

创建数据表

此处只有一个表:message(from ,to,message)

实现数据库操作:

//通过这个类,把数据库连接过程封装一下
//此处,把 DBUtil 作为一个工具类,提供 static 方法,供其它方法来调用
public class DBUtil {//静态成员是跟随类对象的,类对象在整个进程中,只有唯一一份//静态成员相当于也是唯一的实例(单例模式,饿汉模式)private static DataSource dataSource = new MysqlDataSource();static {//使用静态代码块,针对 dataSourse 进行初始化((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java?charactorEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("123456");}//通过这个方法来建立连接public static Connection getConnection() throws SQLException {return dataSource.getConnection();}//通过这个方法来断开连接,释放资源public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet)  {//此处的三个 try catch 分开写更好,避免前面的异常导致后面的代码无法执行if (resultSet != null){try {resultSet.close();} catch (SQLException e) {throw new RuntimeException(e);}}if (statement != null){try {statement.close();} catch (SQLException e) {throw new RuntimeException(e);}}if (connection != null){try {connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}}
}

要插入的数据,是三个变量,要把这三个变量给填充到 Sql 中,就需要占位符

class Message{public String from;public String to;public String message;
}@WebServlet("/message")
public class MessageServlet extends HttpServlet {//使用 List 变量保存所有消息//private List<Message> messagesList = new ArrayList<>();//向服务器提交数据@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ObjectMapper objectMapper = new ObjectMapper();//把 body 中的内容读取出来,解析成 message 对象Message message = objectMapper.readValue(req.getInputStream(),Message.class);//此处,通过一个简单粗暴的方式来完成保存//messagesList.add(message);save(message);//此处的设定状态码可以省略,不设置,默认也是200resp.setStatus(200);}//从服务器获取数据@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ObjectMapper objectMapper = new ObjectMapper();//显示告诉浏览器,数据是 json 格式,并且字符集是 utf8resp.setContentType("applicaion/json; charset=utf8");//objectMapper.writeValue(resp.getWriter(),messagesList);//把 java 对象转换成 json 字符串List<Message> messagesList = load();String jsonResp = objectMapper.writeValueAsString(messagesList);//把字符串写回到响应 body 中resp.getWriter().write(jsonResp);}//提供一对方法//往数据库中存一条消息private void save(Message message) {//JDBC 操作//1、建立连接Connection connection = null;PreparedStatement statement = null;try {connection = DBUtil.getConnection();//2、构造 SQL 语句String sql = "insert into message values(?,?,?)";statement = connection.prepareStatement(sql);statement.setString(1,message.from);statement.setString(2,message.to);statement.setString(3,message.message);//3、执行 SQLstatement.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);}finally {//4、关闭连接DBUtil.close(connection,statement,null);}}//从数据库中取所有消息private List<Message> load(){List<Message> messageList = new ArrayList<>();PreparedStatement statement = null;Connection connection = null;ResultSet resultSet = null;try {//1、和数据库建立连接connection = DBUtil.getConnection();//2、构造 SQLString sql = "select *from message";statement = connection.prepareStatement(sql);//3、执行 SQLresultSet = statement.executeQuery();//4、遍历结果集合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);}}catch (SQLException e){e.printStackTrace();}finally {//5、需要释放资源,断开连接DBUtil.close(connection,statement,resultSet);}return messageList;}
}

相关文章:

表白墙程序

目录 一、页面代码部分 二、设计程序 二、实现 doPost​编辑 三、实现 doGet 四、前端代码部分 五、使用数据库存储数据 一、页面代码部分 在之前的一篇博客中&#xff0c;已经写过了表白墙的页面代码实现&#xff0c;这里就不再重复了 页面代码如下&#xff1a; <!…...

git 本地仓库关联到远程仓库

将本地仓库关联到远程仓库 方式一&#xff1a;远程仓库没有文件 第一步&#xff1a; git init&#xff08;初始化git仓库&#xff09; 第二步&#xff1a; git remote add 地址&#xff08;设置remote地址&#xff09; 第三步&#xff1a; git add . &#xff08;将所有变…...

Introducing Language Guidance in Prompt-based Continual Learning

本文是LLM系列文章&#xff0c;针对《Introducing Language Guidance in Prompt-based Continual Learning》的翻译。 基于提示的持续学习中引入语言指导 摘要1 引言2 相关工作3 背景4 基于提示的持续学习语言指导5 实验6 结论 摘要 持续学习旨在学习一系列任务的单一模型&am…...

Matlab(数值微积分)

目录 1.多项式微分与积分 1.1 微分 1.2 多项式微分 1.3 如何正确的使用Matlab? 1.3.1 Matlab表达多项式 1.3.2 polyval() 多项式求值 1.3.3 polyder()多项式微分 1.4 多项式积分 1.4.1 如何正确表达 1.4.2 polyint() 多项式积分 2.数值的微分与积分 2.1 数值微分 2…...

【数据结构回顾】

数据结构回顾 一、单链表二、单循环链表 一、单链表 #include <stdio.h> #include <stdlib.h>typedef struct Node {int data;Node *next; }Node;Node* initList() {Node *list (Node*)malloc(sizeof(Node));list->data 0;list->next NULL;return list; }…...

QT创建可移动点类

效果如图所示&#xff1a; 创建新类MovablePoint&#xff0c;继承自QWidget. MovablePoint头文件: #ifndef MOVABLEPOINT_H #define MOVABLEPOINT_H#include <QWidget> #include <QPainter> #include <QPaintEvent> #include <QStyleOption> #includ…...

Flutter启动页

效果图 import dart:async; import package:flutter/cupertino.dart; import package:flutter/material.dart; import jumpPage.dart;class TransitPage extends StatefulWidget {const TransitPage({super.key});overrideState<TransitPage> createState() > _Trans…...

读word模板批量生成制式文件

文章目录 1、Maven依赖2、.docx或.doc格式的word模板准备3、读word模板&#xff0c;批量替换代码域&#xff0c;生成文件&#xff0c;demo4、结果展示 1、Maven依赖 <dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagre…...

Node.js crypto模块 加密算法

背景 微信小程序调用飞蛾热敏纸打印机&#xff0c;需要进行参数sig签名校验&#xff0c;使用的是sha1进行加密 // 通过crypto.createHash()函数&#xff0c;创建一个hash实例&#xff0c;但是需要调用md5&#xff0c;sha1&#xff0c;sha256&#xff0c;sha512算法来实现实例的…...

Win11 避坑安装WSL2 Ubuntu22.04

开始之前以管理员身份打开 PowerShell 启用适用于 Linux 的 Windows 子系统 需要先启用“适用于 Linux 的 Windows 子系统”可选功能&#xff0c;然后才能在 Windows 上安装 Linux 分发。 PowerShell然后输入以下命令&#xff1a; dism.exe /online /enable-feature /featur…...

ESP8266+继电器+MQTT+VUE 实现远程开关灯

超详细教程 – ESP8266继电器MQTTVUE 实现远程开关灯 超详细教程 – ESP8266继电器MQTTVUE 实现远程开关灯 接线图 NC&#xff08;通常闭合&#xff09;与COM&#xff08;公共&#xff09;、NO&#xff08;通常开放&#xff09;与COM 是继电器引脚的不同配置&#xff0c;用于不…...

Android中级——四大组件工作过程

四大组件工作过程 ActivityServicestartService()过程bindService()过程 BroadcastReceiver注册过程发送和接收过程 ContentProvider Activity startActivity()最终都会调用到startActivityForResult() public void startActivityForResult(RequiresPermission Intent intent…...

【RabbitMQ】RabbitMQ 服务无法启动。系统出错。发生系统错误 1067。进程意外终止。

问题描述 RabbitMQ 服务无法启动。 rabbitmq-service.bat startRabbitMQ 服务正在启动 . RabbitMQ 服务无法启动。系统出错。发生系统错误 1067。进程意外终止。原因分析 RabbitMQ和Erlang版本不匹配。 解决方案 查询并安装RabbitMQ版本对应Erlang版本 https://www.rabbitm…...

如何理解attention中的Q、K、V?

y直接用torch实现一个SelfAttention来说一说&#xff1a; 1、首先定义三哥线性变换&#xff0c;query&#xff0c;key以及value&#xff1a; class BertSelfAttention(nn.Module):self.query nn.Linear(config.hidden_size, self.all_head_size)#输入768&#xff0c;输出768…...

Redis----取代RabbitMq 和 Kafka的解决方案

背景 已知rabbitmq和kafka作为消息中间件来给程序之间增加异步消息传递功能&#xff0c;这两个中间件都是专业的&#xff0c;功能也很强&#xff0c;但是有的时候过于复杂&#xff0c;对于只有一组消费者的消息队列&#xff0c;使用Redis 就可以轻松搞定。 异步消息队列 读者…...

动态规划之连续乘积最大子数组 连续和最大子数组

一. 连续和最大子数组 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,…...

keil在点击debug无法运行(全速运行)

1、今天发现我之前可以debug的程序&#xff0c;在板子上无法debug了&#xff0c;打断点完全没用 2、换了电脑&#xff0c;带板子过去也这样&#xff0c;之前可以运行的代码都debug不了 3、按照网上的方法&#xff0c;都不行&#xff0c;全速运行&#xff0c;单步执行都是灰色…...

go语言-协程

mOS结构体 每一种操作系统不同的线程信息 g给g0栈给g0协程内存中分配的地址&#xff0c;记录函数跳转信息&#xff0c; 单线程循环 0.x版本 1.0版本 多线程循环 操作系统并不知道Goroutine的存在 操作系统线程执行一个调度循环&#xff0c;顺序执行Goroutine 调度循环非常…...

如何伪造http头,让后端认为是本地访问

0x00 前言 这个知识点纯粹就是为了ctf准备的&#xff0c;很少有系统会出现这种情况。 0x01 正文 1.host头 如果后端从host取值来判断是否是本地就可以通过此方法进行绕过&#xff1a; host: 127.0.0.12.X-Forwarded-For X-Forwarded-For&#xff08;XFF&#xff09;是用来…...

视频剪辑音效处理软件有哪些?视频剪辑软件那个好用

音效是视频剪辑的重要部分&#xff0c;能起到画龙点睛的作用。在短视频平台中&#xff0c;一段出彩的音效能将原本平平无奇的视频变得生动有趣。那么&#xff0c;视频剪辑音效处理软件有哪些&#xff1f;本文会给大家介绍好用的音效处理软件&#xff0c;同时也会介绍视频剪辑音…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...