Servlet实现表白墙
目录
一、表白墙简介
二、代码实现
1、约定前后端交互的接口
2、后端代码实现
3、前端代码实现
三、效果演示
一、表白墙简介
在表白墙页面中包含三个文本框,分别表示表白者,表白对象,表白内容,在文本框中输入内容之后,内容能够保存,并且在下次启动页面的时候也能显示出之前所保存的内容。
二、代码实现
1、约定前后端交互的接口
要实现表白墙,首先就需要约定前后端的交互接口,在实际开发过程中,前端人员只负责前端开发,后端人员负责后端开发,那么就需要约定前端发送什么样的请求,后端处理请求之后再以什么格式将数据返回给前端。
那么对于 POST请求:
POST /message
{from:"XX",to:"XX",message:"xxx"
}
POST响应:
HTTP/1.1 200 OK
{ok:true
}
当用户点击提交按钮之后,就会向HTTP服务器发送一个请求,让服务器把这个信息存储起来。
GET 请求
GET /message
GET响应
HTTP/1.1 200 OK
Content-Type:application/json
{{from:"XX",to:"XX",message:"xxx"},{from:"XX",to:"XX",message:"xxx"},……
}
请求从服务器上获取到之前保存的所有的留言信息,响应是Json格式的数组。
2、后端代码实现
正式写代码之前的准备工作:
需要创建一个maven项目,在这个项目中先引入Servlet依赖,Mysql依赖,以及Jackson依赖并且创建出正确的目录结构。
<dependencies><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.5</version></dependency></dependencies>
web.xml中的内容如下:
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name> </web-app>
首先创建出一个message类定义from,to,message几个变量。
class Message{public String from;public String to;public String message;
}
创建DBUtil连接数据库,并且能够关闭各种资源。
public class DBUtil {private static final String url = "jdbc:mysql://127.0.0.1:3306/message?characterEncoding=utf8&useSSL=false";private static final String user = "root";private static final String password = "1234";public volatile static DataSource dataSource;private static DataSource getDataSource(){if(dataSource == null){synchronized (DBUtil.class){if(dataSource == null){dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setUrl(url);((MysqlDataSource)dataSource).setUser(user);((MysqlDataSource)dataSource).setPassword(password);}}}return dataSource;}public static Connection getConnection() throws SQLException {return getDataSource().getConnection();}public static void closeResource(Connection connection, PreparedStatement statement, ResultSet resultSet){if(resultSet != null){try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if(statement != null){try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if(connection != null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}
在Mysql中创建Message表:
创建MessageServlet类,继承HttpServlet类,重写doGet方法和doPost方法。
在doPost方法中,先设置了响应的内容类型为json格式和字符集为utf-8,然后将请求信息转换成Message对象,再将Message对象的内容存入数据库。然后再向body中写入约定的POST响应的内容。
private ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=utf8");Message message = objectMapper.readValue(req.getInputStream(),Message.class);//将处理的请求信息存入数据库save(message);resp.getWriter().write("{\"ok\":true");}private void save(Message message){Connection connection = null;PreparedStatement statement = null;try {connection = DBUtil.getConnection();String sql = "insert into message value(?,?,?)";statement = connection.prepareStatement(sql);statement.setString(1,message.from);statement.setString(2,message.to);statement.setString(3,message.message);statement.executeUpdate();} catch (SQLException e) {e.printStackTrace();}finally {DBUtil.closeResource(connection,statement,null);}}
在doGet方法中也要先设置响应的内容格式是json,设置字符集为utf-8,然后从数据库中取出之前存储的信息存到链表中,将Message对象转换成字符串写入作为get方法响应的body中。
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=utf8");List<Message> messages = load();String jsonString = objectMapper.writeValueAsString(messages);System.out.println("jsonString:" + jsonString);resp.getWriter().write(jsonString);}private List<Message> load(){Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;List<Message> list = new LinkedList<>();try {connection = DBUtil.getConnection();String sql = "select * from message";statement = connection.prepareStatement(sql);resultSet = statement.executeQuery();while(resultSet.next()){Message message = new Message();message.from = resultSet.getString("from");message.to = resultSet.getString("to");message.message = resultSet.getString("massage");list.add(message);}} catch (SQLException e) {e.printStackTrace();}finally {DBUtil.closeResource(connection,statement,resultSet);}return list;}
3、前端代码实现
需要基于ajax能构造请求并解析响应。
把当前获取到的输入框的内容,构造成一个HTTP POST请求,然后通过ajax发给服务器。
let body = {"from": from,"to": to,"message": message};$.ajax({type: "post",url: "message",contentType: "application/json;charset=utf8",data: JSON.stringify(body),success: function() {alert("提交成功!");},error: function () {alert("提交失败");}});
在每次刷新页面时,要从服务器上获取到消息,将其进行展示。
function getMessages() {$.ajax({type: 'get',url:'message',contentType: 'json',success: function(body) {let container=document.querySelector('.container');console.log(body);for(let message of body) {let row=document.createElement('div');row.innerHTML=message.from+'对'+message.to+'说:'+message.message;row.className='row';//3.把这个新的元素添加到DOM树上container.appendChild(row);}}});
前端完整代码:
<!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 src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script><script>//点击按钮提交的时候,ajax要构造数据发送给服务器//页面加载的时候,从服务器获取消息列表,并且在页面上直接显示。function getMessages() {$.ajax({type: 'get',url:'message',contentType: 'json',success: function(body) {let container=document.querySelector('.container');console.log(body);for(let message of body) {let row=document.createElement('div');row.innerHTML=message.from+'对'+message.to+'说:'+message.message;row.className='row';//3.把这个新的元素添加到DOM树上container.appendChild(row);}}});}getMessages();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='';}// 5.把当前获取到的输入框的内容,构造成一个HTTP POST请求,然后通过ajax发给服务器let body = {"from": from,"to": to,"message": message};$.ajax({type: "post",url: "message",contentType: "application/json;charset=utf8",data: JSON.stringify(body),success: function() {alert("提交成功!");},error: function () {alert("提交失败");}});}</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 ;}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{width:90px;font-size: 20px;}input{width:310px;height: 40px;font-size: 18px;}/*设置提交按钮的样式*/#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>
三、效果演示
点击提交按钮之后:
相关文章:

Servlet实现表白墙
目录 一、表白墙简介 二、代码实现 1、约定前后端交互的接口 2、后端代码实现 3、前端代码实现 三、效果演示 一、表白墙简介 在表白墙页面中包含三个文本框,分别表示表白者,表白对象,表白内容,在文本框中输入内容之后&…...
[python入门㊸] - python测试函数
目录 ❤ 测试函数 ❤ 单元测试和测试用例 ❤ 可通过的测试 ❤ 不能通过的测试 ❤ 测试未通过时怎么办 ❤ 添加新测试 ❤ 测试函数 学习测试,得有测试的代码。下面是一个简单的函数: name_function.py def get_formatted_name(first, last):…...

通讯录文件操作化
宝子,你不点个赞吗?不评个论吗?不收个藏吗? 最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!! 喵喵喵,你对我真的很重…...

为什么 Web3 社交将超越其 Web2 同行
我们最近听到了很多关于 web3 社交媒体平台的消息。但如果你没有跟上,你可能想知道为什么我们已经有了 Twitter、Facebook、Instagram 等,我们还需要 web3 社交。好吧,这一切都取决于谁拥有权力。 在 web2 中,权力掌握在寻求收入最…...

当资深程序员深夜去“打劫”会发生什么?——打家劫舍详解
文章目录一、前言二、概述三、打家劫舍第一晚四、打家劫舍第二晚五、打家劫舍第三晚......一、前言 大家好久不见,正如标题所示,今天我不打算聊一些枯燥的算法理论,我们来聊一聊程序员有多厉害! 注意!!&am…...
linux 线程
文章目录1、线程的概念1.1、进程 vs 线程1.2、线程的种类2、线程的控制2.1、线程的创建2.2、线程的退出2.3、线程的取消2.4、线程的等待2.5、线程的分离2.5、线程清理函数线程清理函数响应的时机线程清理函数不响应的时机3、线程的同步和互斥3.1、锁机制3.1.1、锁的类型3.1.2、…...

Windows 安装appium环境
1 windows Appium环境 1.1 安装Node.js Node.js的安装相对简单,下载安装包安装(安装包node-v19.6.0-x64.msi), nodejs 安装 然后一路狂点下一步就可以了 安装完成后,在终端中输入node -v,显示版本号则表示安装成功 node-v16.13.1 1.2 JDK安装及环境变…...

为什么要在电子产品中使用光耦合器?
介绍 光耦合器不仅可以保护敏感电路,还可以使工程师设计各种硬件应用。光耦合器通过保护元件,可以避免更换元件的大量成本。然而,光耦合器比保险丝更复杂。光耦合器还可以通过光耦合器连接和断开两个电路,从而方便地控制两个电路…...

Vue3 如何实现一个函数式右键菜单(ContextMenus)
前言: 最近在公司 PC 端的项目中使用到了右键出现菜单选项这样的一个工作需求,并且自己现在也在实现一个偶然迸发的 idea( 想用前端实现一个 windows 系统从开机到桌面的 UI),其中也要用到右键弹出菜单这样的一个功能,…...

ffmpeg转码转封装小工具开发
如下图所示,是本人开发的一个转码转封装小工具 其中目标文件视频编码格式支持:H264,H265,VP8,VP9。 目标文件封装格式支持:mp4,mkv,avi,mov,flv。 目标文件音频编码格式支持两个,COPY和AAC&am…...
重入和线程安全
在整个文档中,重入和线程安全用于标记类和函数,从而表明怎样在多线程应用中使用它们。 线程安全函数可以从多个线程同时调用,即使调用使用共享数据也是如此,因为对共享数据的所有引用都是序列化的。也可以从多个线程同时调用重入…...

MySQL数据库06——条件查询(WHERE)
MySQL条件查询,主要是对数据库里面的数据按照一定条件进行筛选,主要依靠的是WHERE语句进行。 先来了解一下基础的条件运算。 关系运算符 逻辑运算符 逻辑运算符优先级:NOT>AND>OR,关系运算符>逻辑运算符 SQL特殊运算符…...

Lesson 6.5 机器学习调参基础理论与网格搜索
文章目录一、机器学习调参理论基础1. 机器学习调参目标及基本方法2. 基于网格搜索的超参数的调整方法2.1 参数空间2.2 交叉验证与评估指标二、基于 Scikit-Learn 的网格搜索调参1. sklearn 中网格搜索的基本说明2. sklearn 中 GridSearchCV 的参数解释3. sklearn 中 GridSearch…...

leetcode: Two Sum
leetcode: Two Sum1. 题目1.1 题目描述2. 解答2.1 baseline2.2 基于baseline的思考2.3 优化思路的实施2.3.1 C中的hashmap2.3.2 实施2.3.3 再思考2.3.4 最终实施3. 总结1. 题目 1.1 题目描述 Given an array of integers nums and an integer target, return indices of the …...

共享模型之无锁(三)
1.原子累加器 示例代码: public class TestAtomicAdder {public static void main(String[] args) {for (int i 0; i < 5; i) {demo(() -> new AtomicLong(0),(adder) -> adder.getAndIncrement());}for (int i 0; i < 5; i) {demo(() -> new LongAdder(),(…...

微信小程序 Springboot校运会高校运动会管理系统
3.1小程序端 小程序登录页面,用户也可以在此页面进行注册并且登录等。 登录成功后可以在我的个人中心查看自己的个人信息或者修改信息等 在广播信息中我们可以查看校运会发布的一些信息情况。 在首页我们可以看到校运会具体有什么项目运动。 在查看具体有什么活动我…...

走进独自开,带你轻松干副业
今天给大家分享一个开发者的福利平台——独自开(点击直接注册),让你在家就能解决收入问题。 文章目录一、平台介绍二、系统案例三、获取收益四、使用平台1、用户注册2、用户认证3、任务报价五、文末总结一、平台介绍 简单说明 独自开信息科技…...

SpringBoot+Vue实现师生健康信息管理系统
文末获取源码 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏…...
数据库第四章节第三次作业内容
1、显示所有职工的基本信息。 2、查询所有职工所属部门的部门号,不显示重复的部门号。 3、求出所有职工的人数。 4、列出最高工和最低工资。 5、列出职工的平均工资和总工资。 6、创建一个只有职工号、姓名和参加工作的新表,名为工作日期表…...

一篇五分生信临床模型预测文章代码复现——FIgure 9.列线图构建,ROC分析,DCA分析 (四)
之前讲过临床模型预测的专栏,但那只是基础版本,下面我们以自噬相关基因为例子,模仿一篇五分文章,将图和代码复现出来,学会本专栏课程,可以具备发一篇五分左右文章的水平: 本专栏目录如下: Figure 1:差异表达基因及预后基因筛选(图片仅供参考) Figure 2. 生存分析,…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...