Servlet small project exercise: realization of confession wall page

Next, we will use this example to feel the processing flow of front-end and back-end handover

First, let's look at a html code like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>告白墙</title>
</head>
<body>
    <!-- 通过内部样式style标签,引入CSS样式 -->
    <style>
        *{
            /* 首先先去除浏览器样式 */
            /* 将 内外边距设置为0,设置盒子模型为向内挤压 */
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        .containner{
            width: 100%;
        }
        h3{
            /* 文本居中 */
            text-align: center;
            /* 上下边距为 20px,左右边距为0 */
            padding: 20px 0;
            font-size: 24px;
        }

        p{
            text-align: center;
            color: #666;
            padding: 10px 0;
        }

        .row{
            width: 400px;
            height: 50px;
            /* 上下外边距为零,左右外边距自适应 */
            /* 就是元素水平居中操作 */
            margin: 0 auto;
            /* 弹性布局 */
            display: flex;
            /* 水平居中 */
            justify-content: center;
            /* 垂直居中 */
            align-items: center;
        }

        .row span{
            width: 60px;
            font-size: 17px;
        }
        .row input{
            width: 300px;
            height: 40px;
            line-height: 40px;
            font-size: 20px;
            text-indent: 0.5em;
            outline: none;
        }

        .row #submit{
            width: 360px;
            height: 40px;
            font-size: 20px;
            line-height: 40px;
            margin: 0 auto;
            color: white;
            background-color: orange;
            border: none;
            border-radius: 15px;
            outline: none;
        }
        /* 当鼠标点击按钮的时候,会改变按钮颜色 */
        .row #submit:active{
            background-color: grey;
        }
    </style>
    <div class="container">
        <h3>表白墙</h3>
        <p>输入后点击提交,会将信息显示在表格中</p>
        <br>
        <div class="row">
            <span>谁: </span>
            <input type="text">
        </div>
        <div class="row">
            <span>对谁: </span>
            <input type="text">
        </div>
        <div class="row">
            <span>说什么: </span>
            <input type="text">
        </div>
        <div class="row">
            <button id="submit">提交</button>
        </div>
    </div>

    <script>
        let submitBtn = document.querySelector('#submit');
        submitBtn.onclick = function(){
            // 1、获取 3个input 文本框中的数据
            let inputs = document.querySelectorAll('input');
            let from = inputs[0].value;
            let to = inputs[1].value;
            let say = inputs[2].value;
            if(from == ''|| to == '' || say == ''){
                // 用户填写的数据,并不完整。所以不提交。
                return;
            }
            // 2、生成一个新的 div,内容就是 三个 input 文本框的内容拼接
            // 再把这个 元素,挂在DOM树上。
            let newDiv = document.createElement('div');
            newDiv.innerHTML = from + "对" + to +"说:" + say;
            newDiv.className = 'row';
            // 将新建节点,挂在 container 这个节点下面
            let container = document.querySelector('.container');
            container.appendChild(newDiv);
        }
    </script>
</body>
</html>

renderings

 

 Since it is the interaction between the front and back ends, we must first figure out the specific process

 

Here is what we want to achieve

 

Next, let's see how to write the specific code

 

complete servlet code


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 MessageWallServlet extends HttpServlet{
    // 因为前后端提交数据的格式是json,我们用jackson这个第三方库来接收处理前端传来的json类型的数据
    private ObjectMapper objectMapper = new ObjectMapper(); // 又因为我们两个方法都有用到这个objectMapper这个类,我们把他放到
    List<Message> messages = new ArrayList<>();
    @Override // 这个接口用来前端从后端获取数据,并显示在页面上
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // super.doGet(req, resp);
        resp.setContentType("application/json; charset=utf-8");  // 设置返回的数据类型
        // 把么message对象转成json格式的字符串

        String body = objectMapper.writeValueAsString(messages);
        resp.getWriter().write(body);  // 把json格式的数据写入返回响应的body当中

    }

    @Override // 这个接口用来后端接收从前端获取到的表单数据并储存起来
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // super.doPost(req, resp);
        Message message = objectMapper.readValue(req.getInputStream(), Message.class); // 读取数据到message对象当中
        messages.add(message); // 最直接的办法就是把这个直接存到内存里
        resp.setContentType("application/json; charset=utf-8"); // 设置返回的编码格式
        // 因为前端给我的数据格式是json类型的,所以我们后端返回给前端的数据也是json类型的(为了统一格式)
        resp.setStatus(200);
        resp.getWriter().write("{\"ok\":1}");
    }
}

 Front-end code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>表白墙</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        .container {
            width: 800px;
            margin: 10px auto;
        }

        .container h2 {
            text-align: center;
            margin: 30px 0px;
        }

        .row {
            height: 50px;
            display: flex;
            justify-content: center;
            margin-top: 5px;
            line-height: 50px;
        }

        .row span {
            height: 50px;
            width: 100px;
            line-height: 50px;
        }

        .row input {
            height: 50px;
            width: 300px;
            line-height: 50px;
        }

        .row button {
            width: 400px;
            height: 50px;
            color: white;
            background-color: orange;
            border: none;
            border-radius: 10px;
        }

        .row button:active {
            background-color: grey;
        }
    </style>
</head>
<body>
<!-- 这是一个顶层容器, 放其他元素 -->
<div class="container">
    <h2>表白墙</h2>
    <div class="row">
        <span>谁</span>
        <input type="text" id="from">
    </div>

    <div class="row">
        <span>对谁</span>
        <input type="text" id="to">
    </div>

    <div class="row">
        <span>说什么</span>
        <input type="text" id="message">
    </div>

    <div class="row">
        <button>提交</button>
    </div>
</div>

<!-- 引入ajax相关的内容,我们可以通过ajax构造get请求和post请求 -->
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
<script>
        let container = document.querySelector('.container');
        let fromInput = document.querySelector('#from');
        let toInput = document.querySelector('#to');
        let messageInput = document.querySelector('#message');
        let button = document.querySelector('button');
        button.onclick = function() {
            // 1. 把用户输入的内容获取到.获取输入框的对象
            let from = fromInput.value;
            let to = toInput.value;
            let message = messageInput.value;
            if (from == '' || to == '' || message == '') {
                return;
            }
            // 2. 构造一个 div, 把这个 div 插入到 .container 的末尾
            let newDiv = document.createElement('div');
            newDiv.className = 'row';
            newDiv.innerHTML = from + " 对 " + to + " 说: " + message;
            // 3. 把 div 挂在 container 里面
            container.appendChild(newDiv);
            // 4. 把之前的输入框内容进行清空
            fromInput.value = '';
            toInput.value = '';
            messageInput.value = '';

            // 5. [新的步骤] 需要把刚才输入框里取到的数据, 构造成 POST 请求, 交给后端服务器!
            // 这里创建出了js一个对象,js对象中的每个方法和属性都是通过键值对这样的形式来表达的,键值对之间采用逗号进行分割,键和值之间用冒号来分割
            // json中的键要求是字符串的形式
            let messageJson = {
                "from": from,
                "to": to,
                "message": message
            };
            // 客户端也就是我们通过ajax发起的请求,这个请求通过网络发给我们的tomcat服务器,进而就会调用我们也就是后端的doxxx方法
            // 之后也就是我们后端通过resp.getWriter.writer构造出http响应,通过我们的tomcat服务器传给我们的客户端,客户端这里收到数据就会触发客户端的代码(ajax的回调success函数)
            $.ajax({
                type: 'post',
                // 相对路径的写法
                url: 'message',
                contentType: 'application/json;charset=utf8',
                // 绝对路径的写法
                // url: '/MessageWall/message',
                data: JSON.stringify(messageJson),
                success: function(body) {
                    alert("提交成功!");
                },
                error: function() {
                    // 会在服务器返回的状态码不是 2xx 的时候触发这个 error.
                    alert("提交失败!");
                }
            });
        }
        // 这个函数在页面加载的时候调用. 通过这个函数从服务器获取到当前的消息列表. 
        // 并且显示到页面上. 
        function load() {
            $.ajax({
                type: 'get',
                url: 'message',
                success: function(body) {
                    // 此处得到的 body 已经是一个 js 对象的数组了. 
                    // ajax 自动帮我们进行类型转换了. 
                    // 本来服务器返回的是 JSON 格式的字符串, ajax 会自动的根据 Content-Type 为 application/json
                    // 对响应的 body 进行解析, 解析成 js 对象. 
                    // 遍历数组的元素, 把内容构造到页面上. 
                    let container = document.querySelector('.container');
                    for (let message of body) {
                        let newDiv = document.createElement('div');
                        newDiv.className = 'row';
                        newDiv.innerHTML = message.from + " 对 " + message.to + " 说 " + message.message;
                        container.appendChild(newDiv);
                    }
                }
            })
        }

        // 函数调用写在这里, 就表示在页面加载的时候来进行执行. 
        load();
        // 整个前后端交互的流程,大致是我们打开这个html页面或者说刷新页面,就会调用我们的load函数,
        //load函数中的ajax构造了一个get请求,发送给tomcat服务器,进而调用我们后端servlet代码中的doGet方法
        // 我们通过doGet方法返回一个http响应,并通过tomcat服务器把响应传给客户端,
        // 客户端接收到数据后就会调用ajax的回调函数succes函数,把数据显示在页面上
        

    </script>
</body>
</html>

Guess you like

Origin blog.csdn.net/weixin_61061381/article/details/127394438