12-代码实战——服务器版表白墙

目录

1.版本一:将数据存到内存中

①约定前后端交互接口

a.添加表白信息:

b.查询表白列表:

②在webapp包下创建message-wall.html前端文件

③在java包下创建AddMessageServlet后端类

④在java包下创建MessageListServlet后端类

2.版本二:将数据存到数据库中

①创建数据库, 创建 messages 表

②在pom.xml中添加MySQL JDBC依赖

③在utils包下创建 DBUtils 类

④在java包下创建AddMessageServletV2后端类

⑤在webapp包下创建message-wallv2.html前端页面

⑥在java包下创建MessageListServletV2后端类


1.版本一:将数据存到内存中

①约定前后端交互接口

所谓 "前后端交互接⼝" 是进⾏ Web 开发中的关键环节。

具体来说,就是允许⻚⾯给服务器发送哪些 HTTP 请求,并且每种请求预期获取什么样的 HTTP 响应。

  • Java里不会直接去操作内存,但后端所有的Servlet类是运行在内存中,这里所说的将数据存到内存中,就是在后端程序中创建一个集合List,List里有一个对象,将数据存到List中,就相当于是存到内存中了。
  • 当不重启Tomcat时,换浏览器都会展示提交的数据;但若重启Tomcat,会释放内存,不会展示提交的数据了。
  • 后端拿到前端传递的3个数据后,将数据放到List里,并且提供一个查询接口。
  • 总共2个接口:①添加表白信息的接口;②查询表白列表的接口。

a.添加表白信息:

  1. url:/message/add
  2. type:POST
  3. 参数:from=xxx&to=yyy&msg=zzz
  4. 返回值:int类型数字

b.查询表白列表:

  1. url:/message/list
  2. type:GET
  3. 参数:无
  4. 返回值:[{"from":"", "to":"", "msg":""}, ...](json对象)

注:不建议写成一个url,不同的type,触达不同的业务。因为ajax使用哪个类型不能决定执行哪个业务方法。

②在webapp包下创建message-wall.html前端文件

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initialscale=1.0"><title>表白墙</title><style>* {margin: 0;padding: 0;}.container {width: 400px;margin: 0 auto;}h1 {text-align: center;padding: 20px 0;}p {color: #666;text-align: center;font-size: 14px;padding: 10px 0;}.row {height: 40px;display: flex;justify-content: center;align-items: center;}span {width: 100px;line-height: 40px;}.edit {width: 200px;height: 30px;}.submit {width: 304px;height: 40px;color: white;background-color: orange;border: none;}.submit:active {background-color: #666;}</style><script src="js/jquery-1.9.1.min.js"></script>
</head>
<body>
<div id="container" class="container"><h1>表白墙</h1><p>输⼊后点击提交, 会将信息显示在表格中</p><div class="row"><span>谁: </span><input id="from" class="edit" type="text"></div><div class="row"><span>对谁: </span><input id="to" class="edit" type="text"></div><div class="row"><span>说什么: </span><input id="message" class="edit" type="text"></div><div class="row"><input type="button" value="提交" class="submit" onclick="mySubmit()"></div><div id="allMsg"></div>
</div>
<script>//添加表白信息function mySubmit() {var from = jQuery("#from");var to = jQuery("#to");var msg = jQuery("#message");//1.非空效验if(from.val().trim() == "") {alert("请先输入from!");from.focus(); //聚焦光标return false; //不走下面的代码了}if(to.val().trim() == "") {alert("请先输入to!");to.focus();return false;}if(msg.val().trim() == "") {alert("请先输入msg!");msg.focus();return false;}//2.ajax提交数据给后端jQuery.ajax({url:"message/add", //提交到后端的地址type:"POST", //提交类型data:{from:from.val(),to:to.val(),msg:msg.val()}, //data是前端给后端提交的key值/参数success:function(result) { //回调函数,匿名函数,result是后端给前端返回的数据,result是一个int类型的值if(result != null && result > 0) {alert("恭喜:添加成功!");//刷新表白列表getAllMsg();} else {alert("抱歉:添加失败,请重试!");}}});}//查询表白列表function getAllMsg() {jQuery.ajax({url:"message/list", //最前面没有'/'type:"GET",data:{},success:function(result) { //result是一个json对象if(result != null && result.length > 0) {//有表白数据var msgHtml = "";for(var i = 0; i < result.length; i++) {msgHtml += '<div class = "row">'+ result[i].from +'对'+ result[i].to +'说'+ result[i].message + '</div>';}jQuery("#allMsg").html(msgHtml);} else if(result != null && result.length == 0) {//没有表白数据console.log("没有表白信息");} else {alert("访问出错!");}}});}//要在页面加载时就执行,那么直接在下面调用即可getAllMsg();
</script>
</body>
</html>

③在java包下创建AddMessageServlet后端类

public class StringUtils {/*** 用来判null和判空的,如果为null或空,返回false* @param str* @return*/public static boolean hasLength(String str) {return !(str == null || str.length() == 0);}
}
import lombok.Getter;
import lombok.Setter;
import utils.StringUtils;
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;
import java.util.ArrayList;
import java.util.List;/*** 添加表白信息*/
@WebServlet("/message/add")
public class AddMessageServlet extends HttpServlet {public static List<Message> msgList = new ArrayList<>();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {int result = -1;//1.得到前端参数并效验String from = req.getParameter("from");String to = req.getParameter("to");String msg = req.getParameter("msg");if(StringUtils.hasLength(from) && StringUtils.hasLength(to) && StringUtils.hasLength(msg)) {//2.将表白对象加入到集合(内存)msgList.add(new Message(from, to, msg));result = 1;}//3.将结果返回给前端resp.setContentType("text/html; charset=utf-8");resp.getWriter().println(result);}
}@Setter
@Getter
class Message {private String from;private String to;private String message;public Message(String from, String to, String message) {this.from = from;this.to = to;this.message = message;}
}

④在java包下创建MessageListServlet后端类

import com.fasterxml.jackson.databind.ObjectMapper;
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;
import java.util.List;/*** 查询表白列表*/
@WebServlet("/message/list")
public class MessageListServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {List<Message> messageList = AddMessageServlet.msgList;resp.setContentType("application/json; charset=utf-8");ObjectMapper objectMapper = new ObjectMapper();resp.getWriter().println(objectMapper.writeValueAsString(messageList));}
}

2.版本二:将数据存到数据库中

把表白墙程序修改成服务器版本JDBC+Servlet,这样即使页面关闭、服务器重启,表白墙的内容也不会丢失。

①创建数据库, 创建 messages 表

②在pom.xml中添加MySQL JDBC依赖

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version>
</dependency>

③在utils包下创建 DBUtils 类

DBUtils 类主要实现以下功能:

  1. 创建 MysqlDataSource 实例,设置 URL, username, password 等属性。
  2. 提供 getConnection ⽅法,和 MySQL 服务器建⽴连接。
  3. 提供 close ⽅法,⽤来释放必要的资源。
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class DBUtils {//单例模式3步://①声明一个私有的构造方法private DBUtils() {}//②提供一个私有的对象属性private static volatile MysqlDataSource mysqlDataSource;private static volatile Connection connection;//③提供一个公共的对外访问的方法,并且这个方法要加volatile和DCL双重效验锁private static MysqlDataSource getMysqlDataSource() {if(mysqlDataSource == null) {synchronized (DBUtils.class) {if(mysqlDataSource == null) {mysqlDataSource = new MysqlDataSource();mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/messagewall?character=utf8&useSSL=true");mysqlDataSource.setUser("root");mysqlDataSource.setPassword("12345678");}}}return mysqlDataSource;}//1.get connectpublic static Connection getConnection() {if(connection == null) { //首次访问synchronized (DBUtils.class) {if(connection == null) {try {MysqlDataSource dataSource = getMysqlDataSource();connection = (Connection) dataSource.getConnection();} catch (SQLException throwables) {throwables.printStackTrace();}}}}return connection;}//2.提供关闭资源的方法public static void close(ResultSet resultSet, PreparedStatement statement, Connection connection) throws SQLException {if(resultSet != null) {resultSet.close();}if(statement != null) {statement.close();}}
}

④在java包下创建AddMessageServletV2后端类

import com.mysql.jdbc.Connection;
import lombok.SneakyThrows;
import utils.DBUtils;
import utils.StringUtils;
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;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;/*** 添加表白信息*/
@WebServlet("/message/add2")
public class AddMessageServletV2 extends HttpServlet {public static List<Message> msgList = new ArrayList<>();@SneakyThrows@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {int result = -1;//1.得到前端参数并效验String from = req.getParameter("from");String to = req.getParameter("to");String msg = req.getParameter("msg");if(StringUtils.hasLength(from) && StringUtils.hasLength(to) && StringUtils.hasLength(msg)) {//2.将表白对象加入到数据库//2.1.得到ConnectConnection connection = DBUtils.getConnection();//2.2.拼接sql,创建执行器String sql = "insert into messages(`from`,`to`,`message`) values(?,?,?)";PreparedStatement statement = connection.prepareStatement(sql);statement.setString(1,from);statement.setString(2,to);statement.setString(3,msg);//2.3.执行执行器,并返回结果result = statement.executeUpdate();//2.4.关闭资源DBUtils.close(null, statement, connection);}//3.将结果返回给前端resp.setContentType("text/html; charset=utf-8");resp.getWriter().println(result);}
}

⑤在webapp包下创建message-wallv2.html前端页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initialscale=1.0"><title>表白墙——连接数据库版本</title><style>* {margin: 0;padding: 0;}.container {width: 400px;margin: 0 auto;}h1 {text-align: center;padding: 20px 0;}p {color: #666;text-align: center;font-size: 14px;padding: 10px 0;}.row {height: 40px;display: flex;justify-content: center;align-items: center;}span {width: 100px;line-height: 40px;}.edit {width: 200px;height: 30px;}.submit {width: 304px;height: 40px;color: white;background-color: orange;border: none;}.submit:active {background-color: #666;}</style><script src="js/jquery-1.9.1.min.js"></script>
</head>
<body>
<div id="container" class="container"><h1>表白墙</h1><p>输⼊后点击提交, 会将信息显示在表格中</p><div class="row"><span>谁: </span><input id="from" class="edit" type="text"></div><div class="row"><span>对谁: </span><input id="to" class="edit" type="text"></div><div class="row"><span>说什么: </span><input id="message" class="edit" type="text"></div><div class="row"><input type="button" value="提交" class="submit" onclick="mySubmit()"></div><div id="allMsg"></div>
</div>
<script>//添加表白信息function mySubmit() {var from = jQuery("#from");var to = jQuery("#to");var msg = jQuery("#message");//1.非空效验if(from.val().trim() == "") {alert("请先输入from!");from.focus(); //聚焦光标return false; //不走下面的代码了}if(to.val().trim() == "") {alert("请先输入to!");to.focus();return false;}if(msg.val().trim() == "") {alert("请先输入msg!");msg.focus();return false;}//2.ajax提交数据给后端jQuery.ajax({url:"message/add2", //提交到后端的地址type:"POST", //提交类型data:{from:from.val(),to:to.val(),msg:msg.val()}, //data是前端给后端提交的key值/参数success:function(result) { //回调函数,匿名函数,result是后端给前端返回的数据,result是一个int类型的值if(result != null && result > 0) {alert("恭喜:添加成功!");//刷新表白列表getAllMsg();} else {alert("抱歉:添加失败,请重试!");}}});}//查询表白列表function getAllMsg() {jQuery.ajax({url:"message/list2", //最前面没有'/',若最前面要有'/',则还需要在'/'后面加上网站的名字,再加上message/list2type:"GET",data:{},//如果要设置传递的ContentType,还要传一个dataType属性success:function(result) { //result是一个json对象if(result != null && result.length > 0) {//有表白数据var msgHtml = "";for(var i = 0; i < result.length; i++) {msgHtml += '<div class = "row">'+ result[i].from +'对'+ result[i].to +'说'+ result[i].message + '</div>';}jQuery("#allMsg").html(msgHtml);} else if(result != null && result.length == 0) {//没有表白数据console.log("没有表白信息");} else {alert("访问出错!");}}});}//要在页面加载时就执行,那么直接在下面调用即可getAllMsg();
</script>
</body>
</html>

⑥在java包下创建MessageListServletV2后端类

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.Connection;
import lombok.SneakyThrows;
import utils.DBUtils;
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;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;/*** 查询表白列表*/
@WebServlet("/message/list2")
public class MessageListServletV2 extends HttpServlet {@SneakyThrows@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//查询数据库中的表白列表List<Message> list = new ArrayList<>();//1.得到connectionConnection connection = DBUtils.getConnection();//2.拼接sql,创建执行器String sql = "select * from messages";PreparedStatement statement = connection.prepareStatement(sql);//3.执行sql,返回resultSet,并循环将数据添加到list中ResultSet resultSet = statement.executeQuery();while(resultSet.next()) {String from = resultSet.getString("from");String to = resultSet.getString("to");String message = resultSet.getString("message");list.add(new Message(from,to,message));}//4.关闭资源DBUtils.close(resultSet, statement, connection);resp.setContentType("application/json; charset=utf-8");ObjectMapper objectMapper = new ObjectMapper();resp.getWriter().println(objectMapper.writeValueAsString(list));}
}

PS:HashMap的遍历写法:

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

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

相关文章

Python案例——采集专栏文章保存成pdf

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 环境使用: python 3.8 >>>>>> 运行代码 pycharm 2022.3 >>>>>> 辅助敲代码 wkhtmltopdf 软件 找助理邀课老师获取 模块使用: 内置模块 re >>>正则表达式 第三方模…

二重积分的解题技巧

计算方法 本节内容一般都应该先画图再思考后续内容较为直观 基本口诀是&#xff1a;后积先定限&#xff0c;限内画条线&#xff0c;先交写下限&#xff0c;后交写上限&#xff08;且下限必须小于上限&#xff09; 结合下图进行解释&#xff0c;后积先定限&#xff0c;对于X-型来…

VMIC-pci-5565反射内存的优势

优势&#xff1a; &#xff08;1&#xff09;实现远程互连的能力 随着仿真实验复杂度的提高&#xff0c;需要多楼宇多试验室间设备的远程互连&#xff0c;通过单模光纤及光纤HUB将远距离的试验室设备进行连接&#xff0c;单模光纤支持的传输距离可达20km。对于距离300m以内的试…

循坏队列CircularQueue

前言 一、CircularQueue 二、特点 三、设计思路 1&#xff09;判空与判满 2&#xff09;链表还是数组实现&#xff1f; 四、实现 1).IsEmpty() 2).IsFull() 3)CircularQueueCreate创建 4&#xff09;CircularQueueEnQueue插入 5&#xff09;CircularQueueDeQueue删除 6&#xf…

C++——string容器常用操作汇总

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 &#x1f4ac;文章目录 一.string容器基本概念二.string容器常用操作✅前言及函数参数的说明一.构造和析构二.string特性操作三.字符操作四.赋值操作五.拼接操作六.交换…

亚马逊云科技积极探索多样化生态合作模式,助力实现可持续发展愿景

2023年6月26日&#xff0c;亚马逊云科技中国峰会在上海世博中心盛大开幕&#xff01;以主题“因构建 而可见”为大家拉开帷幕。当前&#xff0c;越来越多的企业客户&#xff0c;以及当地政府监管机构对企业的要求&#xff0c;都需要企业告知碳足迹&#xff0c;亚马逊云科技提供…

华为OD机试真题 JavaScript 实现【寻找峰值】【牛客练习题】

一、题目描述 给定一个长度为n的数组nums&#xff0c;请你找到峰值并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回任何一个所在位置即可。 1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于&#xff1b; 2.假设 nums[-1] n…

C语言:数据的存储

往期文章 C语言&#xff1a;初识C语言C语言&#xff1a;分支语句和循环语句C语言&#xff1a;函数C语言&#xff1a;数组C语言&#xff1a;操作符详解C语言&#xff1a;指针详解C语言&#xff1a;结构体 目录 往期文章前言1. 数据的类型2. 整型在内存中的存储2.1 原码、反码、…

不知道识别表格的方式有哪些?分享识别表格怎么弄

小明&#xff1a;嘿&#xff0c;小红&#xff01;你知道吗&#xff1f;最近我在整理一堆纸质表格&#xff0c;但是手动输入数据实在太耗时间了&#xff0c;我在想有没有什么方法可以快速识别表格的内容呢&#xff1f; 小红&#xff1a;哦&#xff0c;我听说过有一些方式可以自…

认识固态继电器及其工作原理

什么是固态继电器&#xff0c;有什么优缺点&#xff1f; 固态继电器 简称SSR&#xff0c;又被称之为“无触点开关”它利用电子元件&#xff08;如双向可控硅等半导体器件&#xff09;的开关特性&#xff0c;可到达无触点无火花地接通和断开电路。 固态继电器工作可靠&#…

大数据开发之Hive案例篇14:某个节点HDFS块比较多

文章目录 一. 问题描述二. 解决方案2.1 查看节点安装的组件2.2 排查HDFS配置2.3 排查Yarn配置2.3.1 首先查看下nodemanager的日志2.3.2 查看container分配情况2.3.3 查看调度机制2.3.4 查看集群任务情况2.3.5 集群负载情况2.3.6 resourcemanager与nodemanager是否可以混合部署 …

【ArcGIS Pro二次开发】(44):属性结构描述表【Excel】转空库(批量)

随着县级国土空间总体规划数据库规范的下发&#xff0c;建立标准空库是一项马上就要着手的工作。国空的数据库体量很大&#xff0c;单是要素类就有100多个&#xff0c;不是以前村规数据库能比的&#xff0c;手动建库是不可能的&#xff0c;工具自动建库就是一个很合理的选择。 …