JavaEE-实现一个服务器版本的“表白墙”
创始人
2025-05-28 10:51:46

目录

  • 实现一个服务器版本的“表白墙”
    • 第一个接口
    • 第二个接口
    • 后端开发
      • 1.创建项目(maven)
      • 2.引入依赖
      • 3.创建目录结构
      • 4.编写代码
      • 5/6. 打包和部署
      • 7. 验证
      • 初步后端代码
    • 前端代码
      • 后端代码优化

实现一个服务器版本的“表白墙”

实现的这个表白墙,就通过服务器,来保存这里的消息数据。
从而进一步的做到“持久化”存储~~

在实现这个程序的时候,就需要先考虑清楚,客户端和服务器如何进行交互~
约定前后端交互的接口~
(自定义应用层协议)

既然是搞一个服务器,服务器就得提供一些服务,具体是提供啥样的服务?以及这些服务该如何触发?

对于表白墙来说,主要要提供两个接口~

  1. 告诉服务器,当前留言了一条啥样的数据~(当用户点击提交按钮的时候,就会给服务器发送一个HTTP请求,让服务器把这个消息给存储下来)
  2. 从服务器获取到,当前都有哪些留言数据~(当页面加载,就需要从服务器获取到曾经存储的这些消息内容)

第一个接口

约定好,为了实现这个效果,客户端要发送一个啥样的HTTP请求,服务器返回一个啥样的HTTP响应~

请求:
POST /message
{from: "黑猫",to: "白猫",message: "喵" 
}

或者

POST /messageWall
from=黑猫&to=白猫&message=喵

或者

GET /message?from=黑猫&to=白猫&message=喵

或者

POST /message{f: "黑猫",t: "白猫",m: "喵" }

按照上述的思路发散开,有无数种方式来约定请求格式!
方法可以变,路径可以变,参数的名字可以变~

这么多的约定方式,到底采取哪一种?
哪种都可以!只要能够明确下来其中的一种,并且在后续编写前端/后端代码的时候能够严格执行,就是ok的。
这也是约定前后端接口的意义!
自定义协议!(约束程序员的自由,不能随便乱写代码~)

当前就是用第一种方式!

请求:
POST /message
{from: "黑猫",to: "白猫",message: "喵" 
}响应:
HTTP/1.1 200 OK
{ok: true
}

第二个接口

请求:
GET /message响应:
HTTP/1.1 200 OK
Content-Type:application/json
[{from: "黑猫",to: "白猫", message: "喵",},{from: "黑猫",to: "白猫", message: "喵",},{from: "黑猫",to: "白猫", message: "喵",},
]

确定接口之后,就可以编写代码了~

后端开发

先进行准备工作.

1.创建项目(maven)

在这里插入图片描述

2.引入依赖

引入Servlet,去中央仓库找~
在这里插入图片描述
在这里插入图片描述
接下来就是jackson
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.创建目录结构

在这里插入图片描述

Archetype Created Web Application

4.编写代码

在这里插入图片描述
这个和前面约定的前后端交互接口是匹配的~

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;@WebServlet("/message")
public class MessageServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 处理提交消息请求resp.getWriter().write("hello post");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取消息列表resp.getWriter().write("hello get");}
}

5/6. 打包和部署

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7. 验证

在这里插入图片描述

初步后端代码

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.ArrayList;
import java.util.List;class Message {public String from;public String to;public String message;
}@WebServlet("/message")
public class MessageServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();private List messages = new ArrayList<>();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 处理提交消息请求Message message = objectMapper.readValue(req.getInputStream(), Message.class);// 最简单的保存方法就是保存在内存中messages.add(message);// 通过 ContentType 来告知页面,返回的数据是 json格式// 有了这样的声明,此时 jquery ajax 就会自动的帮我们把字符串转成 js 对象// 如果没有, jquery ajax 就只是当成字符串来处理resp.setContentType("application/json; charset=utf8");resp.getWriter().write("{  \"ok\":true }");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取消息列表,只要把消息列表中的内容整个返回给客户端即可// 此处需要使用 ObjectMapper 把 Java 对象,转成 JSON 格式字符串String jsonString = objectMapper.writeValueAsString(messages);System.out.println("jsonString: " +jsonString);resp.getWriter().write(jsonString);}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当前我们已经把后端逻辑编写完毕,接下来来写前端代码

前端代码

在webapp里面放~
在这里插入图片描述



表白墙

表白墙

输入后点击提交, 会将信息显示在表格中

谁:
对谁:
说什么:

在这里插入图片描述
当页面加载的时候,我们就能够看到有一个这个ajax请求,这个请求就是从服务器获取消息列表的~

在这里插入图片描述
此处看到是空着了,刚才不是明明往服务器上提交了三条记录?
在这里插入图片描述
刚刚这个代码是把消息保存到了list中,内容中的数据我们一旦程序重启就会丢失。
因此,上述逻辑,只能保证页面刷新后数据不丢失,而不能保证服务器重启后数据不丢失~
当然,要想更加彻底解决这个问题,就需要把数据保存到硬盘上(可以是文件,也可以是数据库)
在这里插入图片描述
当前确实可以证明,即使页面关闭之后,之前提交的消息是不丢失的~
(页面加载的时候,从服务器获取到了消息列表,并显示在了浏览器页面中)

后端代码优化

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;public class DBUtil {private static final String URL = "jdbc:mysql://127.0.0.1:3306/java107?characterEncoding=utf8&useSSL=false";private static final String USERNAME = "root";private static final String PASSWORD = "1234";private volatile static DataSource dataSource = null;private static DataSource getDataSource() {if (dataSource == null) {synchronized (DBUtil.class) {if (dataSource == null) {dataSource = new MysqlDataSource();((MysqlDataSource) dataSource).setURL(URL);((MysqlDataSource) dataSource).setUser(USERNAME);((MysqlDataSource) dataSource).setPassword(PASSWORD);}}}return dataSource;}public static Connection getConnection() throws SQLException {return getDataSource().getConnection();}public static void close(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();}}}
}
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.io.Reader;
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;
}@WebServlet("/message")
public class MessageServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 处理提交消息请求Message message = objectMapper.readValue(req.getInputStream(), Message.class);// 最简单的保存方法就是保存在内存中//messages.add(message);// 通过 ContentType 来告知页面,返回的数据是 json格式// 有了这样的声明,此时 jquery ajax 就会自动的帮我们把字符串转成 js 对象// 如果没有, jquery ajax 就只是当成字符串来处理save(message);resp.setContentType("application/json;charset=utf8");resp.getWriter().write("{ \"ok\":true }");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取消息列表,只要把消息列表中的内容整个返回给客户端即可// 此处需要使用 ObjectMapper 把 Java 对象,转成 JSON 格式字符串List messages = load();String jsonString = objectMapper.writeValueAsString(messages);System.out.println("jsonString: " + jsonString);resp.setContentType("application/json;charset=utf8");resp.getWriter().write(jsonString);}private void save(Message message) {// 把一条消息保存到数据库中Connection connection = null;PreparedStatement statement = null;try {// 1. 和数据库建立连接connection = DBUtil.getConnection();// 2. 构造 SQLString 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 {DBUtil.close(connection, statement, null);}}private List load() {// 从数据库中获取到所有的消息List messages = new ArrayList<>();Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;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("message");messages.add(message);}} catch (SQLException e) {throw new RuntimeException(e);} finally {DBUtil.close(connection, statement, resultSet);}return messages;}
}

相关内容

热门资讯

分享实测“新猴王大厅究竟有没有... 您好:新猴王大厅这款游戏可以开挂,确实是有挂的,需要软件加微信【5951795】,很多玩家在新猴王大...
科技通报“中至江西麻将到底有没... 您好:中至江西麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8383742】很多玩家在这款...
重大来袭“二八杠 辅助挂”开挂... 您好:这款游戏可以开挂,确实是有挂的,需要了解加客服微信【2278274】很多玩家在这款游戏中打牌都...
分享实测“微友互娱透视软件辅助... 您好:微友互娱这款游戏可以开挂,确实是有挂的,需要软件加微信【4194432】,很多玩家在微友互娱这...
「玩家攻略」“福建十三道是不是... 您好:福建十三道这款游戏可以开挂,确实是有挂的,需要了解加客服微信【6670747】很多玩家在这款游...