• 【Java EE初阶二十六】简单的表白墙(二)


    2. 后端服务器部分

    2.1 服务器分析

    2.2 代码编写

    2.2.2 前端发起一个ajax请求

    2.2.3 服务器读取上述请求,并计算出响应

             服务器需要使用 jackson 读取到前端这里的数据,并且进行解析:

    代码运行图:

    2.2.4 回到前端代码,处理服务器返回的响应

    1、对服务器的响应做出反应

            此处 success 回调函数,不是立即执行的,而是在浏览器收到服务器返回的成功这样的响应的时候,才会执行到 function,这个函数的第一个参数,就是响应数据的 body 中的内容,如下所示:

            为了和请求对应上,一般服务器返回的数据,也会按照 json 格式来组织,代码如下所示:

            当前浏览器和服务器所实现的效果如下:

    服务器收到的请求:

    浏览器收到的响应:

     

            当前数据已经被提交到服务器保存了,目前还需要能够把服务器的数据拿回到客户端页面上并显示;

    2、把服务器的数据拿回到客户端页面上,并显示;

           至于为啥还要从服务器拿消息?
    (1、当前页面上显示的数据,也是在浏览器内存中保存的,刷新页面/关闭了重新打开,之前的数据就没了
    (2、其他的客户端打开页面也是有数据的.

    编写代码步骤如下:

    1)客户端在页面加载的时候,发起一个 http 请求

    1. $.ajax({
    2. type: 'get',
    3. url: 'message',
    4. success: function(body) {
    5. //处理服务器返回来的数据,使用json格式的数组
    6. });

    2)服务器收到这个请求,要处理这个请求并生成响应,

            服务器收到的每条消息,都转成了 Message 对象,放到上述 List 中了,返回的结果, 也就是这个 List 的数据.,需要把 List 里的每个 Message 取出来, 转成json 字符串,最终拼到一起,得到了响应结果;

    注意:jackson 本身就支持把 List 类型的数据转成json 数组

            jackson 看到了 messagelist 是一个 List 类型,转成的json 字符串就是一个json 数组,
    jackson 自动遍历 List 里的每个元素,把每个元素,分别都转成 json 字符串;

            这一部分代码如下:

    1. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    2. // 通过这个方法来处理当前获取消息列表的 get 请求. 不需要解析参数, 直接返回数据即可.
    3. resp.setStatus(200);
    4. resp.setContentType("application/json; charset=utf8");
    5. // 从数据库查询
    6. List messageList = null;
    7. try {
    8. messageList = load();
    9. } catch (SQLException e) {
    10. throw new RuntimeException(e);
    11. }
    12. String respJson = objectMapper.writeValueAsString(messageList);
    13. resp.getWriter().write(respJson);
    14. }

            确保这几个代码的执行顺序:
            setStatus 和 setContentType 必须在 getWriter 前面,否则可能不会生效(构造出一个非法的 http 响应报文)
    3)、客户端收到响应,就需要针对响应数据进行解析处理,把响应中的信息,构造成页面元素,并显示出来.

            上图中body 就是服务器返回的响应,即数据中 json 格式的数组;当响应中, header 带有 Content-Type: application/ison,jquery 就会自动的把 json字符串, 解析成js 对象了。

            如果没有带 Content-Type: application/json,就需要通过js 代码 JSON.parse 方法来手动把 json 字符申转成js 对象;

            我们要构造的内容如下图所示:

            将构造出来的上面的这个 div,添加到下面这个 div 的末尾:

            html页面上的任何一个元素,都可以用一个js 对象来表示;反之,js 的对象也可以设置到页面中,

    3. 把数据存储到数据库中

            数据库引入到代码中,主要有一下几个步骤:

    1)、引入数据库的依赖

    1. mysql
    2. mysql-connector-java
    3. 5.1.47

    2)、建库建表.建库建表需要用到 sql;
    3)、编写数据库代码--->JDBC

    后端代码如下所示:

    1. import com.fasterxml.jackson.databind.ObjectMapper;
    2. import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.annotation.WebServlet;
    5. import javax.servlet.http.HttpServlet;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. import javax.sql.DataSource;
    9. import java.io.IOException;
    10. import java.sql.Connection;
    11. import java.sql.PreparedStatement;
    12. import java.sql.ResultSet;
    13. import java.sql.SQLException;
    14. import java.util.ArrayList;
    15. import java.util.List;
    16. class Message {
    17. public String from;
    18. public String to;
    19. public String message;
    20. @Override
    21. public String toString() {
    22. return "Message{" +
    23. "from='" + from + '\'' +
    24. ", to='" + to + '\'' +
    25. ", message='" + message + '\'' +
    26. '}';
    27. }
    28. }
    29. @WebServlet("/message")
    30. public class MessageServlet extends HttpServlet {
    31. private ObjectMapper objectMapper = new ObjectMapper();
    32. // 引入数据库, 此时 messageList 就不再需要了.
    33. // private List messageList = new ArrayList<>();
    34. private DataSource dataSource = new MysqlDataSource();
    35. @Override
    36. public void init() throws ServletException {
    37. // 1. 创建数据源
    38. ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/message_wall?characterEncoding=utf8&useSSL=false");
    39. ((MysqlDataSource) dataSource).setUser("root");
    40. ((MysqlDataSource) dataSource).setPassword("111111");
    41. }
    42. @Override
    43. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    44. // 读取前端发来的数据, 把这个数据保存到服务器这边.
    45. Message message = objectMapper.readValue(req.getInputStream(), Message.class);
    46. System.out.println("请求中收到的 message: " + message);
    47. // 最简单的办法, 直接在内存中保存. 可以使用一个集合类, 把所有收到的 message 都存到内存中.
    48. // 很明显, 保存到内存, 并非是一个非常合理的办法. 后续一旦重启服务器, 数据丢失了.
    49. // 相比之下, 把这个数据持久化存储到数据库中, 更科学的.
    50. // messageList.add(message);
    51. // 插入数据库
    52. try {
    53. save(message);
    54. } catch (SQLException e) {
    55. throw new RuntimeException(e);
    56. }
    57. // 返回一个响应
    58. resp.setStatus(200);
    59. resp.getWriter().write("ok");
    60. // resp.setContentType("application/json");
    61. // resp.getWriter().write("{ ok: true }");
    62. }
    63. @Override
    64. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    65. // 通过这个方法来处理当前获取消息列表的 get 请求. 不需要解析参数, 直接返回数据即可.
    66. resp.setStatus(200);
    67. resp.setContentType("application/json; charset=utf8");
    68. // 从数据库查询
    69. List messageList = null;
    70. try {
    71. messageList = load();
    72. } catch (SQLException e) {
    73. throw new RuntimeException(e);
    74. }
    75. String respJson = objectMapper.writeValueAsString(messageList);
    76. resp.getWriter().write(respJson);
    77. }
    78. private void save(Message message) throws SQLException {
    79. // 通过这个方法把 message 插入到数据库中
    80. // 1. 建立连接
    81. Connection connection = dataSource.getConnection();
    82. // 2. 构造 SQL
    83. String sql = "insert into message values(?, ?, ?)";
    84. PreparedStatement statement = connection.prepareStatement(sql);
    85. statement.setString(1, message.from);
    86. statement.setString(2, message.to);
    87. statement.setString(3, message.message);
    88. // 3. 执行 SQL
    89. statement.executeUpdate();
    90. // 4. 回收资源
    91. statement.close();
    92. connection.close();
    93. }
    94. private List load() throws SQLException {
    95. // 通过这个方法从数据库读取到 message.
    96. // 1. 建立连接
    97. Connection connection = dataSource.getConnection();
    98. // 2. 构造 SQL
    99. String sql = "select * from message";
    100. PreparedStatement statement = connection.prepareStatement(sql);
    101. // 3. 执行 sql
    102. ResultSet resultSet = statement.executeQuery();
    103. // 4. 遍历结果集合
    104. List messageList = new ArrayList<>();
    105. while (resultSet.next()) {
    106. Message message = new Message();
    107. message.from = resultSet.getString("from");
    108. message.to = resultSet.getString("to");
    109. message.message = resultSet.getString("message");
    110. messageList.add(message);
    111. }
    112. // 5. 回收资源
    113. resultSet.close();
    114. statement.close();
    115. connection.close();
    116. // 6. 返回 messageList
    117. return messageList;
    118. }
    119. }

    ps:关于表白墙小项目就到这里了,后续如有不足会维持更新的!!!

  • 相关阅读:
    Azure - 机器学习实战:快速训练、部署模型
    如何本地windows电脑通过scp下载vps服务器内的文件
    【无标题】右键菜单
    数据库系统概论(超详解!!!)第三节 关系数据库标准语言SQL(Ⅴ)
    从Mpx资源构建优化看splitChunks代码分割
    大二Web课程设计——张家界旅游网站设计与实现(HTML+CSS+JavaScript)
    优橙内推天津专场——5G网络优化(中高级)工程师
    Python猜数字小游戏
    首都博物京韵展,监测系统实现文物科技保护
    工业摄像机参数计算
  • 原文地址:https://blog.csdn.net/2202_76101487/article/details/136329520