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

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

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

<!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>

效果图

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

 

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

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

完整的servlet代码


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}");
    }
}

 前端代码:

<!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>

猜你喜欢

转载自blog.csdn.net/weixin_61061381/article/details/127394438