Servlet小小项目练习:表白墙页面的实现

妖狐艹你老母 2023-09-24 12:42 105阅读 0赞

下面我们将通过这个实例,去感受前后端交接的处理流程

首先我们先来看一个这样的html代码:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>告白墙</title>
  8. </head>
  9. <body>
  10. <!-- 通过内部样式style标签,引入CSS样式 -->
  11. <style>
  12. *{
  13. /* 首先先去除浏览器样式 */
  14. /* 将 内外边距设置为0,设置盒子模型为向内挤压 */
  15. margin: 0;
  16. padding: 0;
  17. box-sizing: border-box;
  18. }
  19. .containner{
  20. width: 100%;
  21. }
  22. h3{
  23. /* 文本居中 */
  24. text-align: center;
  25. /* 上下边距为 20px,左右边距为0 */
  26. padding: 20px 0;
  27. font-size: 24px;
  28. }
  29. p{
  30. text-align: center;
  31. color: #666;
  32. padding: 10px 0;
  33. }
  34. .row{
  35. width: 400px;
  36. height: 50px;
  37. /* 上下外边距为零,左右外边距自适应 */
  38. /* 就是元素水平居中操作 */
  39. margin: 0 auto;
  40. /* 弹性布局 */
  41. display: flex;
  42. /* 水平居中 */
  43. justify-content: center;
  44. /* 垂直居中 */
  45. align-items: center;
  46. }
  47. .row span{
  48. width: 60px;
  49. font-size: 17px;
  50. }
  51. .row input{
  52. width: 300px;
  53. height: 40px;
  54. line-height: 40px;
  55. font-size: 20px;
  56. text-indent: 0.5em;
  57. outline: none;
  58. }
  59. .row #submit{
  60. width: 360px;
  61. height: 40px;
  62. font-size: 20px;
  63. line-height: 40px;
  64. margin: 0 auto;
  65. color: white;
  66. background-color: orange;
  67. border: none;
  68. border-radius: 15px;
  69. outline: none;
  70. }
  71. /* 当鼠标点击按钮的时候,会改变按钮颜色 */
  72. .row #submit:active{
  73. background-color: grey;
  74. }
  75. </style>
  76. <div class="container">
  77. <h3>表白墙</h3>
  78. <p>输入后点击提交,会将信息显示在表格中</p>
  79. <br>
  80. <div class="row">
  81. <span>谁: </span>
  82. <input type="text">
  83. </div>
  84. <div class="row">
  85. <span>对谁: </span>
  86. <input type="text">
  87. </div>
  88. <div class="row">
  89. <span>说什么: </span>
  90. <input type="text">
  91. </div>
  92. <div class="row">
  93. <button id="submit">提交</button>
  94. </div>
  95. </div>
  96. <script>
  97. let submitBtn = document.querySelector('#submit');
  98. submitBtn.onclick = function(){
  99. // 1、获取 3个input 文本框中的数据
  100. let inputs = document.querySelectorAll('input');
  101. let from = inputs[0].value;
  102. let to = inputs[1].value;
  103. let say = inputs[2].value;
  104. if(from == ''|| to == '' || say == ''){
  105. // 用户填写的数据,并不完整。所以不提交。
  106. return;
  107. }
  108. // 2、生成一个新的 div,内容就是 三个 input 文本框的内容拼接
  109. // 再把这个 元素,挂在DOM树上。
  110. let newDiv = document.createElement('div');
  111. newDiv.innerHTML = from + "对" + to +"说:" + say;
  112. newDiv.className = 'row';
  113. // 将新建节点,挂在 container 这个节点下面
  114. let container = document.querySelector('.container');
  115. container.appendChild(newDiv);
  116. }
  117. </script>
  118. </body>
  119. </html>

效果图

935eb1d46b5d4c39bd5665a6f93a091b.png

既然是前后端的交互我们就首先要搞清楚具体的流程

de645cd2da964bf191ae7fd021720c18.png

下面是我们的要达到的效果

97e29013aece4534814c1f9f7176f557.png

接下来让我们看看具体的代码怎么写

4d7b0ebf0ee24bf794c3c0ec5e7f9855.png

完整的servlet代码

  1. import com.fasterxml.jackson.databind.ObjectMapper;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. // 我们后端用这个类来接收前端提交的数据
  11. class Message {
  12. public String from;
  13. public String to;
  14. public String message;
  15. }
  16. // 这里只是把我们的数据存到了我们的内存中,服务器一重启,数据就没了
  17. @WebServlet("/message")
  18. public class MessageWallServlet extends HttpServlet{
  19. // 因为前后端提交数据的格式是json,我们用jackson这个第三方库来接收处理前端传来的json类型的数据
  20. private ObjectMapper objectMapper = new ObjectMapper(); // 又因为我们两个方法都有用到这个objectMapper这个类,我们把他放到
  21. List<Message> messages = new ArrayList<>();
  22. @Override // 这个接口用来前端从后端获取数据,并显示在页面上
  23. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  24. // super.doGet(req, resp);
  25. resp.setContentType("application/json; charset=utf-8"); // 设置返回的数据类型
  26. // 把么message对象转成json格式的字符串
  27. String body = objectMapper.writeValueAsString(messages);
  28. resp.getWriter().write(body); // 把json格式的数据写入返回响应的body当中
  29. }
  30. @Override // 这个接口用来后端接收从前端获取到的表单数据并储存起来
  31. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  32. // super.doPost(req, resp);
  33. Message message = objectMapper.readValue(req.getInputStream(), Message.class); // 读取数据到message对象当中
  34. messages.add(message); // 最直接的办法就是把这个直接存到内存里
  35. resp.setContentType("application/json; charset=utf-8"); // 设置返回的编码格式
  36. // 因为前端给我的数据格式是json类型的,所以我们后端返回给前端的数据也是json类型的(为了统一格式)
  37. resp.setStatus(200);
  38. resp.getWriter().write("{\"ok\":1}");
  39. }
  40. }

前端代码:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>表白墙</title>
  8. <style>
  9. * {
  10. padding: 0;
  11. margin: 0;
  12. box-sizing: border-box;
  13. }
  14. .container {
  15. width: 800px;
  16. margin: 10px auto;
  17. }
  18. .container h2 {
  19. text-align: center;
  20. margin: 30px 0px;
  21. }
  22. .row {
  23. height: 50px;
  24. display: flex;
  25. justify-content: center;
  26. margin-top: 5px;
  27. line-height: 50px;
  28. }
  29. .row span {
  30. height: 50px;
  31. width: 100px;
  32. line-height: 50px;
  33. }
  34. .row input {
  35. height: 50px;
  36. width: 300px;
  37. line-height: 50px;
  38. }
  39. .row button {
  40. width: 400px;
  41. height: 50px;
  42. color: white;
  43. background-color: orange;
  44. border: none;
  45. border-radius: 10px;
  46. }
  47. .row button:active {
  48. background-color: grey;
  49. }
  50. </style>
  51. </head>
  52. <body>
  53. <!-- 这是一个顶层容器, 放其他元素 -->
  54. <div class="container">
  55. <h2>表白墙</h2>
  56. <div class="row">
  57. <span></span>
  58. <input type="text" id="from">
  59. </div>
  60. <div class="row">
  61. <span>对谁</span>
  62. <input type="text" id="to">
  63. </div>
  64. <div class="row">
  65. <span>说什么</span>
  66. <input type="text" id="message">
  67. </div>
  68. <div class="row">
  69. <button>提交</button>
  70. </div>
  71. </div>
  72. <!-- 引入ajax相关的内容,我们可以通过ajax构造get请求和post请求 -->
  73. <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
  74. <script>
  75. let container = document.querySelector('.container');
  76. let fromInput = document.querySelector('#from');
  77. let toInput = document.querySelector('#to');
  78. let messageInput = document.querySelector('#message');
  79. let button = document.querySelector('button');
  80. button.onclick = function() {
  81. // 1. 把用户输入的内容获取到.获取输入框的对象
  82. let from = fromInput.value;
  83. let to = toInput.value;
  84. let message = messageInput.value;
  85. if (from == '' || to == '' || message == '') {
  86. return;
  87. }
  88. // 2. 构造一个 div, 把这个 div 插入到 .container 的末尾
  89. let newDiv = document.createElement('div');
  90. newDiv.className = 'row';
  91. newDiv.innerHTML = from + " 对 " + to + " 说: " + message;
  92. // 3. 把 div 挂在 container 里面
  93. container.appendChild(newDiv);
  94. // 4. 把之前的输入框内容进行清空
  95. fromInput.value = '';
  96. toInput.value = '';
  97. messageInput.value = '';
  98. // 5. [新的步骤] 需要把刚才输入框里取到的数据, 构造成 POST 请求, 交给后端服务器!
  99. // 这里创建出了js一个对象,js对象中的每个方法和属性都是通过键值对这样的形式来表达的,键值对之间采用逗号进行分割,键和值之间用冒号来分割
  100. // json中的键要求是字符串的形式
  101. let messageJson = {
  102. "from": from,
  103. "to": to,
  104. "message": message
  105. };
  106. // 客户端也就是我们通过ajax发起的请求,这个请求通过网络发给我们的tomcat服务器,进而就会调用我们也就是后端的doxxx方法
  107. // 之后也就是我们后端通过resp.getWriter.writer构造出http响应,通过我们的tomcat服务器传给我们的客户端,客户端这里收到数据就会触发客户端的代码(ajax的回调success函数)
  108. $.ajax({
  109. type: 'post',
  110. // 相对路径的写法
  111. url: 'message',
  112. contentType: 'application/json;charset=utf8',
  113. // 绝对路径的写法
  114. // url: '/MessageWall/message',
  115. data: JSON.stringify(messageJson),
  116. success: function(body) {
  117. alert("提交成功!");
  118. },
  119. error: function() {
  120. // 会在服务器返回的状态码不是 2xx 的时候触发这个 error.
  121. alert("提交失败!");
  122. }
  123. });
  124. }
  125. // 这个函数在页面加载的时候调用. 通过这个函数从服务器获取到当前的消息列表.
  126. // 并且显示到页面上.
  127. function load() {
  128. $.ajax({
  129. type: 'get',
  130. url: 'message',
  131. success: function(body) {
  132. // 此处得到的 body 已经是一个 js 对象的数组了.
  133. // ajax 自动帮我们进行类型转换了.
  134. // 本来服务器返回的是 JSON 格式的字符串, ajax 会自动的根据 Content-Type 为 application/json
  135. // 对响应的 body 进行解析, 解析成 js 对象.
  136. // 遍历数组的元素, 把内容构造到页面上.
  137. let container = document.querySelector('.container');
  138. for (let message of body) {
  139. let newDiv = document.createElement('div');
  140. newDiv.className = 'row';
  141. newDiv.innerHTML = message.from + " 对 " + message.to + " 说 " + message.message;
  142. container.appendChild(newDiv);
  143. }
  144. }
  145. })
  146. }
  147. // 函数调用写在这里, 就表示在页面加载的时候来进行执行.
  148. load();
  149. // 整个前后端交互的流程,大致是我们打开这个html页面或者说刷新页面,就会调用我们的load函数,
  150. //load函数中的ajax构造了一个get请求,发送给tomcat服务器,进而调用我们后端servlet代码中的doGet方法
  151. // 我们通过doGet方法返回一个http响应,并通过tomcat服务器把响应传给客户端,
  152. // 客户端接收到数据后就会调用ajax的回调函数succes函数,把数据显示在页面上
  153. </script>
  154. </body>
  155. </html>

发表评论

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

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

相关阅读