表白墙(服务器版)

落日映苍穹つ 2023-09-27 16:43 27阅读 0赞

在这里插入图片描述

文章目录

  • 一、准备工作
  • 二、前后端交互
    • 后端
    • 前端
  • 三、数据库版本

一、准备工作

我们之前实现过这样一个表白墙,具体前端代码参考 表白墙 这篇文章
46dac79fbca3421290d9a95004dfb3c1.png
但是我们之前写的这个表白墙有一些问题:
1.如果我们刷新页面/重新开启,之前的数据就不见了
2.我们只能在单机操作,其他机器不能看见
于是我们现在就来解决这些问题,让服务器来存储用户提交的数据,当有新的浏览器打开该页面时,在从服务器获取数据,首先我们创建一个web项目,引入相关依赖
在这里插入图片描述
在src下创建webapp/WEB-INF/web.xml,并在pom.xml下面引入mysql依赖,servlet依赖和jackson依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>mysql</groupId>
  4. <artifactId>mysql-connector-java</artifactId>
  5. <version>5.1.49</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>javax.servlet</groupId>
  9. <artifactId>javax.servlet-api</artifactId>
  10. <version>3.1.0</version>
  11. <scope>provided</scope>
  12. </dependency>
  13. <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
  14. <dependency>
  15. <groupId>com.fasterxml.jackson.core</groupId>
  16. <artifactId>jackson-databind</artifactId>
  17. <version>2.14.1</version>
  18. </dependency>
  19. </dependencies>

引入依赖之后记得刷新,
然后创建servelet类,并指明访问路径为message,具体实现我们后面在具体写

  1. @WebServlet("/messagewell")
  2. public class MessageWellServlet extends HttpServlet {

然后我们将我们之前写好的表白墙前端代码导入到webapp目录下,大家之前去我之前的文章里复制即可
在这里插入图片描述

二、前后端交互

既然我们想要进行前后端交互,就得约定好接口,前端给服务器发什么样的HTTP请求,服务器返回什么样的HTTP响应
1.页面加载,浏览器从服务器获取表白信息
前端请求: GET/message
响应: HTTP/1.1 200OK,返回json数组形式的数据

2.提交表白信息,浏览器将表白信息发送到服务器
前端请求:POST/message,发送json形式的数据
响应:HTTP/1.1 200OK

后端

在这里插入图片描述
我们前端提交数据后,使用json格式发给服务器,我们需要构建一个这样的类,然后使用jackson进行接收数据

  1. class Message {
  2. public String from;
  3. public String to;
  4. public String message;
  5. }

我们来实现一下当前端提交数据时,我们服务器的处理

  1. List<Message> list = new ArrayList<>();
  2. @Override
  3. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  4. ObjectMapper objectMapper = new ObjectMapper();
  5. //将body中的内容进行读取
  6. Message message = objectMapper.readValue(req.getInputStream(),Message.class);
  7. //将获取到的message对象加入到成员变量list中
  8. list.add(message);
  9. //设置响应状态码
  10. resp.setStatus(200);
  11. }

有了doPost的基础,我们doGET方法就简单的多了,直接将list中的所有数据写回响应即可

  1. @Override
  2. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3. //设置响应格式
  4. resp.setContentType("application/json; charset=utf8");
  5. ObjectMapper mapper = new ObjectMapper();
  6. mapper.writeValue(resp.getWriter(),list);
  7. }

在这里插入图片描述
该方法是将java对象转成json字符串,并将其写入到响应中,如果大家觉得这个方法看起来费劲的话,大家也可以换一种方法

  1. @Override
  2. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3. //设置响应格式
  4. resp.setContentType("application/json; charset=utf8");
  5. ObjectMapper mapper = new ObjectMapper();
  6. //将java对象转成json字符串
  7. String jsonResp = mapper.writeValueAsString(list);
  8. resp.getWriter().write(jsonResp);
  9. }

前端

我们前端需要发送两部分请求:
1.post,当我们点击提交表白信息的时候发起
2.get,我们加载页面的时候发起

我们使用VScode打开前端代码,引入jquery依赖

  1. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>

在这里插入图片描述
然后我们使用ajax构造请求
在这里插入图片描述
我们看一下我们之前写的前端代码,当我们onclick提交时,我们只是构造了一个div加入到页面内,现在我们增加一下,让其提交给后端
在这里插入图片描述

我们将输入框读取到的数据,构建成一个js对象,但是我们body只能传输字符串不能传输对象,于是我们需要将对象转成一个json格式的字符串

  1. strBody = JSON.stringify(body);
  2. strBody = JSON.stringify(body);
  3. $.ajax({
  4. type: 'post',
  5. url: 'messagewell',
  6. data: strBody,
  7. contentType: "application/json; charset=utf8",
  8. success: function(body) {
  9. console.log("数据提交成功");
  10. }
  11. });

然后使用ajax将数据提交给服务器,我们来测试一下当前代码,我们使用tomcat部署,并访问
在这里插入图片描述
在这里插入图片描述
然后我们点击提交,我们看到确认发送了一个HTTP请求
在这里插入图片描述
在这里插入图片描述
这里就证明我们提交表白信息这一前后端操作是正确的
接下来我们来实现当我们刷新页面时读取服务器数据,我们使用ajax发送GET请求

  1. //当我们页面加载时,给服务器发送GET请求,获取数据,添加到页面中
  2. $.ajax({
  3. type: 'get',
  4. url: 'messagewell',
  5. success: function(body) {
  6. //此数body就是一个js格式的字符串,但是我们这里需要js对象数组
  7. //jquery会帮我们将js对象字符串解析成js对象数组
  8. for(let message of body) {
  9. let rowDiv = document.createElement('div');
  10. rowDiv.className = 'row';
  11. rowDiv.innerHTML = message.from + ' 对 ' + message.to + ' 说 ' + message.message;
  12. containerDiv.appendChild(rowDiv);
  13. }
  14. }
  15. })

我们这里的body,jquery为我们将js格式字符串解析为js对象数组,我们需要创建div标签,将每个js对象的数据添加到里面,然后将div添加到页面即可
现在我们重启服务器来验证一下
在这里插入图片描述
我们先随便提交几条数据,然后我们来尝试一下刷新页面
在这里插入图片描述
我们刷新后,数据仍然在页面上,我们在刷新的同时,给服务器发送了一个GET请求
在这里插入图片描述
同样的服务器将所有的表白信息响应给我们的浏览器
在这里插入图片描述
这样一个服务器版本的表白墙就实现完成了,大家需要注意的是我们的数据是在内存中存放的,如果我们重启服务器之后,之前的数据就不见了,如果想要持久化存储就需要借助数据库了

三、数据库版本

我们这里只需要创建一张message信息表,表中有三个属性(from,to,message)
在这里插入图片描述
大家需要注意我们在创表过程中的一些问题,因为我们的from和to是我们mysql中的关键字,所以我们需要加上`,接下来我们就使用JDBC来和数据库进行交互操作
因为我们数据库连接操作和关闭资源需要频频使用,所以我们这里创建一个DBUtil工具类来简化操作

  1. import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
  2. import javax.sql.DataSource;
  3. import java.sql.*;
  4. //DButi作为工具类,供其他类使用
  5. public class DBUtil {
  6. private static DataSource dataSource = new MysqlDataSource();
  7. static{
  8. //对datasuorce初始化
  9. ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/zd?characterEncoding=utf8&useSSL=false");
  10. ((MysqlDataSource)dataSource).setUser("root");
  11. ((MysqlDataSource)dataSource).setPassword("自己的密码");
  12. }
  13. //通过该方法获取连接
  14. public static Connection getConnection() throws SQLException {
  15. return dataSource.getConnection();
  16. }
  17. public static void close(Connection connection, PreparedStatement statement,ResultSet resultSet) {
  18. if(resultSet != null) {
  19. try {
  20. resultSet.close();
  21. } catch (SQLException e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. if(statement != null) {
  26. try {
  27. statement.close();
  28. } catch (SQLException e) {
  29. e.printStackTrace();
  30. }
  31. }
  32. if(connection != null) {
  33. try {
  34. connection.close();
  35. } catch (SQLException e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. }
  40. }

接下来我们在servlet类下实现两个方法,save()将我们前端提交的数据添加到数据库中,load()将我们数据库中的所有数据返回给前端

  1. public void save(Message message) {
  2. Connection connection = null;
  3. PreparedStatement statement = null;
  4. try {
  5. //获取连接
  6. connection = DBUtil.getConnection();
  7. //构造sql语句
  8. String sql = "insert into message values(?,?,?)";
  9. statement = connection.prepareStatement(sql);
  10. statement.setString(1,message.from);
  11. statement.setString(2,message.to);
  12. statement.setString(3,message.message);
  13. //执行sql
  14. statement.executeUpdate();
  15. }catch (SQLException e) {
  16. e.printStackTrace();
  17. }finally {
  18. //关闭连接
  19. DBUtil.close(connection,statement,null);
  20. }
  21. }
  22. public List<Message> load() {
  23. Connection connection = null;
  24. PreparedStatement statement = null;
  25. ResultSet resultSet = null;
  26. List<Message> messageList = new ArrayList<>();
  27. try {
  28. //获取连接
  29. connection = DBUtil.getConnection();
  30. //构造sql语句
  31. String sql = "select * from message";
  32. statement = connection.prepareStatement(sql);
  33. resultSet = statement.executeQuery();
  34. while (resultSet.next()) {
  35. Message message = new Message();
  36. message.from = resultSet.getString("from");
  37. message.to = resultSet.getString("to");
  38. message.message = resultSet.getString("message");
  39. messageList.add(message);
  40. }
  41. }catch (SQLException e) {
  42. e.printStackTrace();
  43. }finally {
  44. //关闭连接
  45. DBUtil.close(connection,statement,resultSet);
  46. }
  47. return messageList;
  48. }

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

发表评论

表情:
评论列表 (有 0 条评论,27人围观)

还没有评论,来说两句吧...

相关阅读