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. 生存分析,…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...

