表白墙程序

迈不过友情╰ 2023-10-15 10:32 226阅读 0赞

目录

一、页面代码部分

二、设计程序

二、实现 doPost编辑

三、实现 doGet

四、前端代码部分

五、使用数据库存储数据


一、页面代码部分

6920c963e8d04c1783b1c3bcd2e855b7.png

在之前的一篇博客中,已经写过了表白墙的页面代码实现,这里就不再重复了

页面代码如下:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>表白墙</title>
  6. </head>
  7. <body>
  8. <div class="container">
  9. <h1>表白墙</h1>
  10. <p>输入后点击提交,会将信息显示在表格中</p>
  11. <div class="row">
  12. <span>谁:</span>
  13. <input type="text" class="edit">
  14. </div>
  15. <div class="row" >
  16. <span>对谁:</span>
  17. <input type="text" class="edit">
  18. </div>
  19. <div class="row">
  20. <span>说什么:</span>
  21. <input type="text" class="edit">
  22. </div>
  23. <div class="row">
  24. <input type="button" value="提 交" id="submit">
  25. </div>
  26. <script>
  27. let submitButton=document.querySelector('#submit');
  28. submitButton.onclick=function(){
  29. //1.先获取到编辑框的内容
  30. let edits=document.querySelectorAll('.edit');
  31. //依靠.value来获得其输入框的值
  32. let from=edits[0].value;
  33. let to=edits[1].value;
  34. let message=edits[2].value;
  35. console.log(from,to,message);
  36. //这里是对用户输入进行合法的校验,看用户输入是否合法
  37. if(from==''||to==' '||message==''){
  38. return;
  39. }
  40. //2.根据内容,构造HTML元素(.row里面包含用户输入的话)
  41. //createElement:创建一个元素
  42. let row=document.createElement('div');
  43. row.className='row';
  44. row.innerHTML=from+'对'+to+'说:'+message;
  45. //3.把这个新的元素添加到DOM树上
  46. let container=document.querySelector('.container');
  47. container.appendChild(row);
  48. //4.清空原来的输入框
  49. for(let i=0;i<edits.length;i++){
  50. edits[i].value='';
  51. }
  52. }
  53. </script>
  54. <style>
  55. /*去除浏览器默认样式:内边距,外边距,内边框和外边框不会撑大盒子*/
  56. *{
  57. margin:0;
  58. padding: 0;
  59. box-sizing: border-box;
  60. }
  61. /*margin:0 auto :意思是 中央居中*/
  62. .container{
  63. width: 400px;
  64. margin:0 auto;
  65. }
  66. /*padding:20px auto :h1标签:上下间距20*/
  67. h1{
  68. text-align:center;
  69. padding:20px auto;
  70. }
  71. p{
  72. text-align:center;
  73. color:#666;
  74. padding: 10px 0;
  75. font-size:14px;
  76. }
  77. /*display:flex:基于弹性布局
  78. justify-content:center:水平居中
  79. align-items:center:垂直居中
  80. */
  81. .row{
  82. height:50px ;
  83. display: flex;
  84. justify-content: center;
  85. align-items:center;
  86. }
  87. /*现在对于span和input的长度进行调整*/
  88. span{
  89. width:90px;
  90. font-size: 20px;
  91. }
  92. input{
  93. width:310px;
  94. height: 40px;
  95. font-size: 18px;
  96. }
  97. /*现在处理一下 提交 按钮
  98. 首先,提交按钮宽度和父元素一样宽
  99. 其次,设置字体颜色和背景颜色
  100. 然后,border:none:作用:为了去除黑边框
  101. border-radius:设置四个角角为圆矩形
  102. font-size:设置 提交 字体的大小
  103. */
  104. #submit{
  105. width: 400px;
  106. color: white;
  107. background-color:orange;
  108. border:none;
  109. border-radius:5px;
  110. font-size: 18px;
  111. }
  112. /*点击 提交 按钮 就会改变其背景颜色*/
  113. #submit:active{
  114. background-color: black;
  115. }
  116. </style>
  117. </div>
  118. </body>
  119. </html>

二、设计程序

之前写的页面有两个非常严重的问题:

1、如果刷新页面 / 关闭页面 重开,之前输入的消息就不见了

2、如果一个机器上输入了数据,第二个机器是看不到的(这些数据都是在本地浏览器中)

解决思路:

让服务器来存储用户提交的数据,由服务器保存

当由新的浏览器打开页面的时候,再从服务器获取数据

此处服务器就可以用来存档和读档的操作

写 web 程序,务必要重点考虑前后端如何交互,也就是约定好前后端交互的数据格式

这个过程,称为 设计前后端交互接口

请求时什么样的,响应是什么样的,浏览器什么时候发送请求,浏览器按照什么格式来解析….

那么哪些环节涉及到前后端交互呢?

1、点击提交,浏览器把表白信息发送到服务器这里

2、页面加载,浏览器从服务器获取到表白信息

1、点击提交,浏览器把表白信息发送到服务器这里

998b7b7601b74d67b3ab8f7e6e20e189.png

2、页面加载,浏览器从服务器获取到表白信息

bf5871b103464a238c913f4b4dbfc930.png

此处的约定,没有固定的强制要求,只要保证能够实现必要的需求即可,此处的目的是为了前后端可以对上号

32cc3cb1ba1f41ce9790a2f37614a0f1.png

注意:这里的路径得和之前约定的保持一致


" class="reference-link">二、实现 doPostcd28ed8b8dce4d85ae1af6ca95055bb6.png

我们要先定义一个类,描述请求的 body 内容,方便 jackson 进行 json 解析

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

然后使用 List 来存储数据

  1. //使用 List 变量保存所有消息
  2. private List<Message> messagesList = new ArrayList<>();
  3. //向服务器提交数据
  4. @Override
  5. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  6. ObjectMapper objectMapper = new ObjectMapper();
  7. //把 body 中的内容读取出来,解析成 message 对象
  8. Message message = objectMapper.readValue(req.getInputStream(),Message.class);
  9. //此处,通过一个简单粗暴的方式来完成保存
  10. messagesList.add(message);
  11. //此处的设定状态码可以省略,不设置,默认也是200
  12. resp.setStatus(200);
  13. }

doPost 做的事情,就是把解析的 message 往 List 里面添加


三、实现 doGet

另一方面,实现 doGet ,也就是把 List 的结果,返回给前端

071975188a7b4bae8c5ed24d14bdeaf7.png

响应数据,也是一个 json 数据

基于 objectMapper 的 writeValue 方法,就可以把 List 转换成 json 格式

b8480adf75624d76960bd1f13837302b.png

这个方法,同时完成了把 java 对象,转换成 json 和把 json 字符串写到响应对象中

第一个参数是 Writer 对象,表示转成的 json 字符串,往哪个地方去写,第二个参数就是当前存储消息的 List ,意思是要把哪个对象转换成 json

如果分成两步,就是这样写的:43800a6e19214968983dc68f750dec95.png

  1. //从服务器获取数据
  2. @Override
  3. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  4. ObjectMapper objectMapper = new ObjectMapper();
  5. //显示告诉浏览器,数据是 json 格式,并且字符集是 utf8
  6. resp.setContentType("applicaion/json; charseet=utf8");
  7. objectMapper.writeValue(resp.getWriter(),messagesList);
  8. }

针对 doGet ,只是把 MessageList 给转换成 json 字符串,返回给浏览器

  1. class Message{
  2. public String from;
  3. public String to;
  4. public String message;
  5. }
  6. @WebServlet("/message")
  7. public class MessageServlet extends HttpServlet {
  8. //使用 List 变量保存所有消息
  9. private List<Message> messagesList = new ArrayList<>();
  10. //向服务器提交数据
  11. @Override
  12. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  13. ObjectMapper objectMapper = new ObjectMapper();
  14. //把 body 中的内容读取出来,解析成 message 对象
  15. Message message = objectMapper.readValue(req.getInputStream(),Message.class);
  16. //此处,通过一个简单粗暴的方式来完成保存
  17. messagesList.add(message);
  18. //此处的设定状态码可以省略,不设置,默认也是200
  19. resp.setStatus(200);
  20. }
  21. //从服务器获取数据
  22. @Override
  23. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  24. ObjectMapper objectMapper = new ObjectMapper();
  25. //显示告诉浏览器,数据是 json 格式,并且字符集是 utf8
  26. resp.setContentType("applicaion/json; charset=utf8");
  27. //objectMapper.writeValue(resp.getWriter(),messagesList);
  28. //把 java 对象转换成 json 字符串
  29. String jsonResp = objectMapper.writeValueAsString(messagesList);
  30. //把字符串写回到响应 body 中
  31. resp.getWriter().write(jsonResp);
  32. }
  33. }

写到这里,表白墙的后端就大功告成了,我们可以打开 postman 对代码进行测试

当前这只是给前端返回 json 字符串,要想成为键值对,还需要额外的代码


四、前端代码部分

接下来,我们来编写前端代码,也就是让页面能够发起上述请求,并解析响应

post 是点击提交按钮的时候发起,get 是页面加载的时候发起

b94257ae84334ef2a4e76c3f96f94c03.png

这个代码是在定义一个 js 对象(类似于 json 的键值对)

key 其实是字符串,value 则是 js 中的变量/常量

js 中要求, 对象中的 key 务必是 字符串,所以这里的 “” 可以省略

当前 body 是个 js 对象,不是字符串,网络传输,只能串字符串,不能传对象

所以,我们需要把目前这个对象转成字符串

d267e530a48847ff9a8d7e2dfad9a7f4.png

js 内置了转换 json 的库

  1. //4、[新增] 给服务器发起 post 请求,把上述数据提交到服务器
  2. let body = {
  3. from :from,
  4. to:to,
  5. message:msg
  6. };
  7. strBody = JSON.stringify(body);
  8. console.log("strBody: " + strBody);
  9. $.ajax({
  10. type:'post',
  11. url:'message',
  12. data:strBody,
  13. contentType:"application/json;charset=utf8",
  14. success:function(body){
  15. console,log("数据发布成功");
  16. }
  17. });

接下来需要实现下 读档操作,让 ajax 发送 GET 请求

  1. //[新增] 在页面加载的时候,发送 GET 请求,从服务器获取到数据并添加到页面中
  2. $.ajax({
  3. type:'get',
  4. url:'message',
  5. success:function(body){
  6. //此处拿到的 body 就是一个 js 的对象数组了
  7. //本来服务器返回的是一个 json 格式的字符串,但是 jquery 的 ajax 可以自动识别,
  8. //自动帮我们把 json 字符串转成 js 对象数组
  9. //接下来,遍历这个数组,把元素取出来,并且构造到页面中即可
  10. for(let message of body){
  11. //针对每个元素构造一个 div
  12. let row=document.createElement('div');
  13. row.className='row';
  14. row.innerHTML=message.from +'对'+message.to +'说:'+message.message;
  15. containerDiv.appendChild(rowDiv);
  16. }
  17. }
  18. });

五、使用数据库存储数据

当前我们的数据是在内存(变量) 中保存的,重启服务器就没了

要想持久化保存,就需要写入文件中(硬盘)

1、直接使用 流对象 写入文本文件

2、借助数据库

创建数据表

此处只有一个表:message(from ,to,message)

097f57b37669481f96ada1e47e912c1e.png

实现数据库操作:

  1. //通过这个类,把数据库连接过程封装一下
  2. //此处,把 DBUtil 作为一个工具类,提供 static 方法,供其它方法来调用
  3. public class DBUtil {
  4. //静态成员是跟随类对象的,类对象在整个进程中,只有唯一一份
  5. //静态成员相当于也是唯一的实例(单例模式,饿汉模式)
  6. private static DataSource dataSource = new MysqlDataSource();
  7. static {
  8. //使用静态代码块,针对 dataSourse 进行初始化
  9. ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java?charactorEncoding=utf8&useSSL=false");
  10. ((MysqlDataSource)dataSource).setUser("root");
  11. ((MysqlDataSource)dataSource).setPassword("123456");
  12. }
  13. //通过这个方法来建立连接
  14. public static Connection getConnection() throws SQLException {
  15. return dataSource.getConnection();
  16. }
  17. //通过这个方法来断开连接,释放资源
  18. public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {
  19. //此处的三个 try catch 分开写更好,避免前面的异常导致后面的代码无法执行
  20. if (resultSet != null){
  21. try {
  22. resultSet.close();
  23. } catch (SQLException e) {
  24. throw new RuntimeException(e);
  25. }
  26. }
  27. if (statement != null){
  28. try {
  29. statement.close();
  30. } catch (SQLException e) {
  31. throw new RuntimeException(e);
  32. }
  33. }
  34. if (connection != null){
  35. try {
  36. connection.close();
  37. } catch (SQLException e) {
  38. throw new RuntimeException(e);
  39. }
  40. }
  41. }
  42. }

a347729f011444b99aea954f2ec9598f.png

要插入的数据,是三个变量,要把这三个变量给填充到 Sql 中,就需要占位符

  1. class Message{
  2. public String from;
  3. public String to;
  4. public String message;
  5. }
  6. @WebServlet("/message")
  7. public class MessageServlet extends HttpServlet {
  8. //使用 List 变量保存所有消息
  9. //private List<Message> messagesList = new ArrayList<>();
  10. //向服务器提交数据
  11. @Override
  12. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  13. ObjectMapper objectMapper = new ObjectMapper();
  14. //把 body 中的内容读取出来,解析成 message 对象
  15. Message message = objectMapper.readValue(req.getInputStream(),Message.class);
  16. //此处,通过一个简单粗暴的方式来完成保存
  17. //messagesList.add(message);
  18. save(message);
  19. //此处的设定状态码可以省略,不设置,默认也是200
  20. resp.setStatus(200);
  21. }
  22. //从服务器获取数据
  23. @Override
  24. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  25. ObjectMapper objectMapper = new ObjectMapper();
  26. //显示告诉浏览器,数据是 json 格式,并且字符集是 utf8
  27. resp.setContentType("applicaion/json; charset=utf8");
  28. //objectMapper.writeValue(resp.getWriter(),messagesList);
  29. //把 java 对象转换成 json 字符串
  30. List<Message> messagesList = load();
  31. String jsonResp = objectMapper.writeValueAsString(messagesList);
  32. //把字符串写回到响应 body 中
  33. resp.getWriter().write(jsonResp);
  34. }
  35. //提供一对方法
  36. //往数据库中存一条消息
  37. private void save(Message message) {
  38. //JDBC 操作
  39. //1、建立连接
  40. Connection connection = null;
  41. PreparedStatement statement = null;
  42. try {
  43. connection = DBUtil.getConnection();
  44. //2、构造 SQL 语句
  45. String sql = "insert into message values(?,?,?)";
  46. statement = connection.prepareStatement(sql);
  47. statement.setString(1,message.from);
  48. statement.setString(2,message.to);
  49. statement.setString(3,message.message);
  50. //3、执行 SQL
  51. statement.executeUpdate();
  52. } catch (SQLException e) {
  53. throw new RuntimeException(e);
  54. }finally {
  55. //4、关闭连接
  56. DBUtil.close(connection,statement,null);
  57. }
  58. }
  59. //从数据库中取所有消息
  60. private List<Message> load(){
  61. List<Message> messageList = new ArrayList<>();
  62. PreparedStatement statement = null;
  63. Connection connection = null;
  64. ResultSet resultSet = null;
  65. try {
  66. //1、和数据库建立连接
  67. connection = DBUtil.getConnection();
  68. //2、构造 SQL
  69. String sql = "select *from message";
  70. statement = connection.prepareStatement(sql);
  71. //3、执行 SQL
  72. resultSet = statement.executeQuery();
  73. //4、遍历结果集合
  74. while (resultSet.next()){
  75. Message message = new Message();
  76. message.from = resultSet.getString("from");
  77. message.to = resultSet.getString("to");
  78. message.message = resultSet.getString("message");
  79. messageList.add(message);
  80. }
  81. }catch (SQLException e){
  82. e.printStackTrace();
  83. }finally {
  84. //5、需要释放资源,断开连接
  85. DBUtil.close(connection,statement,resultSet);
  86. }
  87. return messageList;
  88. }
  89. }

发表评论

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

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

相关阅读