Servlet模版引擎使用示例

1. 动态页面的渲染方式

1.1 服务器端渲染

HTML如下:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>猜数字</title>
</head>
<body>
<div>
    <form action="guessNum" method="post">
        <input type="text" name="toGuess">
        <input type="submit" value="">
    </form>
</div>
<div>结果:</div>
</body>
</html>

Java代码如下:

package Thymeleaf;

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.Random;

@WebServlet("/guessNum")
public class GuessNumServlet extends HttpServlet {
    Random random = new Random();
    private int toGuess = 0;

    // 使用这个 doGet 来从服务器获取到猜数字的初始页面
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        toGuess = random.nextInt(100) + 1;
        resp.getWriter().write("<!DOCTYPE html>\n" +
                "<html lang=\"zh\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>猜数字</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "<div>\n" +
                "    <form action=\"guessNum\" method=\"post\">\n" +
                "        <input type=\"text\" name=\"toGuess\">\n" +
                "        <input type=\"submit\" value=\"猜\">\n" +
                "    </form>\n" +
                "</div>\n" +
                "<div>结果:</div>\n" +
                "</body>\n" +
                "</html>");
    }

    // 使用 doPost 来从服务器获取到 "带有猜测结果" 的页面
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        // 先根据用户提交的数字来比较一下看看结果
        int user = Integer.parseInt(req.getParameter("toGuess"));
        String result = "";
        if (user < toGuess) {
            result = "低了";
        } else if (user > toGuess) {
            result = "高了";
        } else {
            result = "答对了";
        }
        resp.getWriter().write("<!DOCTYPE html>\n" +
                "<html lang=\"zh\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>猜数字</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "<div>\n" +
                "    <form action=\"guessNum\" method=\"post\">\n" +
                "        <input type=\"text\" name=\"toGuess\">\n" +
                "        <input type=\"submit\" value=\"猜\">\n" +
                "    </form>\n" +
                "</div>\n" +
                "<div>结果:</div>\n" + result +
                "</body>\n" +
                "</html>");
    }
}

会发现在不使用模版引擎的情况下,当前的Java代码(代表着业务逻辑)和HTML代码(代表着用户界面)混合在一起,非常的不友好。尤其是HTML比较长,比较复杂的时候。

1.2 客户端渲染「Thymeleaf」

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>MessageWal</title>
</head>

<body>
    <style>
        * {
            margin: 0px;
            padding: 0px;
            /* 因为有padding的存在会导致内容把盒子撑开而变大:这里加上border-box之后就不撑开盒子 */
            box-sizing: border-box;
        }

        .container {
            width: 600px;
            margin: 0 auto;
        }

        h1 {
            text-align: center;
            padding: 20px 0px;
        }

        p {
            font-size: 12px;
            color: grey;
            padding: 10px 0px;
            text-align: center;
        }

        .row {
            display: flex;
            height: 40px;
            justify-content: center;
            align-items: center;
        }

        .row span {
            width: 100px;
        }

        .row .edit {
            width: 200px;
            height: 38px;
        }

        .row .submit {
            width: 300px;
            height: 40px;
            background-color: orange;
            /* 清除边框线条 */
            border: none;
            color: white;
        }

        .row .submit:active {
            background-color: grey;
        }
    </style>

    <div class="container">
        <h1>表白墙</h1>
        <p>输入后点击提交,将会吧信息显示在表格中</p>
        <form action="message" method="post">
            <div class="row">
                <span>谁:</span>
                <input type="text" class="edit" name="from">
            </div>

            <div class="row">
                <span>对谁:</span>
                <input type="text" class="edit" name="to">
            </div>

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

            <div class="row">
                <input type="submit" value="提交" class="submit">
            </div>
        </form>

        <!-- 这个 div 就通过玄幻的方式来获取内容 -->
        <div class="row" th:each="message:${messages}">
            <span th:text="${message.from}"></span><span th:text="${message.to}"></span>
            说:
            <span th:text="${message.message}"></span>
        </div>
    </div>

    <script>
        // 现在通过 java 代码来动态生成当前的页面内容,不需要前端生成这里的标签
        // let submitButton = document.querySelector(".submit");
        // submitButton.onclick = function () {
        //     // 1.现获取到输入边框里的内容
        //     let edits = document.querySelectorAll(".edit");
        //     let from = edits[0].value, to = edits[1].value, message = edits[2].value;
        //     if (!(from == "" || to == "" | message == "")) {
        //         console.log(from + "对" + to + ":" + message);
        //         // 2.根据输入的内容,构造HTML元素,添加到页面中
        //         let row = document.createElement("div");
        //         row.className = "row";
        //         row.innerHTML = from + "对" + to + "说:" + message;
        //         let container = document.querySelector(".container");
        //         container.appendChild(row);
        //         // 3.把上次输入的内容清空;
        //         for (let i = 0; i < edits.length; ++i) {
        //             edits[i].value = "";
        //         }
        //     }
        // }
    </script>
</body>

</html>

Servlet代码

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

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;

class Message {
    public String from;
    public String to;
    public String message;
}

@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    // 1.先创建引擎
    private TemplateEngine engine = new TemplateEngine();

    // 保存所有的消息
    private ArrayList<Message> messages = new ArrayList<>();

    @Override
    public void init() throws ServletException {
        // 2.创建解析器
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(getServletContext());
        resolver.setPrefix("/WEB-INF/template/");
        resolver.setSuffix(".html");
        resolver.setCharacterEncoding("UTF-8");
        engine.setTemplateResolver(resolver);
    }

    // 获取初始页面
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 把当前的模版读取加载过来,把消息 messages 给替换进去,并返回页面
        resp.setContentType("text/html;charset=UTF-8");
        WebContext webContext = new WebContext(req, resp, getServletContext());
        webContext.setVariable("messages", messages);
        engine.process("MessageWall", webContext, resp.getWriter());
    }
    // 执行新增页面

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 读取用户提交的数据,添加到 messages 列表中去,然后再返回一个完整页面
        // 设置请求的访问方式是必要的,否则 Servlet 读到的中文可能是乱码
        req.setCharacterEncoding("UTF-8");
        Message message = new Message();
        message.from = req.getParameter("from");
        message.to = req.getParameter("to");
        message.message = req.getParameter("message");
        messages.add(message);


        // 返回完整页面
        resp.setContentType("text/html;charset=UTF-8");
        WebContext webContext = new WebContext(req, resp, getServletContext());
        webContext.setVariable("messages", messages);
        engine.process("MessageWall", webContext, resp.getWriter());
    }
}

/*
Servlet 模版引擎目的:能够更放比啊的返回一个页面;没有模版引擎,直接在 java 代码中,通过拼装字符串的方式来返回 html【非常麻烦容易出错】
有模版引擎,直接把 html 放到 .html文件中,并且把其中一些需要动态生成的数据,使用占位符来占个位置。在 java 代码中加载这个 html 模版,并且对其中的占位符进行动态替换
1.java 代码中的处理
    Thymeleaf 的模版引擎对象功能就是进行数据的动态替换,核心方法就是 process("模版名", webContext, resp.getWriter())
    ServletContextTemplateResolver 解析器对象:加载模版文件
    WebContext:简单键值对。通过这个对象,把模版中的占位符和 java 的变量关联起来
    ServletContext:这个对象不是 Thymeleaf 的,是 Servlet 自带的上下文对象,每个 webapp 都有一个上下文。一个 webapp 中的若干个 Servlet 共享同一个上下文对象。这个上下文对象存在的目的就是为了让这些 Servlet 之间共享数据,或者互相通信
    初始化:固定套路,复制粘贴

2.模版代码中的处理
    Thymeleaf 中所支持的 "占位符"
    th:text把变量的值作为 html 标签内容
    th:[属性]把变量的值作为 html 标签的属性值
    th:if条件判定
    th:each循环
 */

文件目录
在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值