0
点赞
收藏
分享

微信扫一扫

模板引擎认识

文章目录

一、服务器渲染VS客户端渲染

服务器生成动态页面有两种方式:服务器渲染客户端渲染

服务器渲染

特点:

优点:

缺点:

客户端渲染

特点:

优点:

缺点:

二、服务器版简易猜数字游戏

2.1 无模板引擎

没有模板还想要服务器返回一个完整的 html ,方法只能是将 html 代码通过 resp.getWriter().write() 来以“text/html;charset=utf-8”的数据格式写在网页上,并将需要动态变换的数据通过字符串拼接的方法进行

//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>Document</title>
</head>
<body>
    <form action="guess" method="post"> 
        <input type="text" name="Num">
        <input type="submit" value="猜">
        <div>
            结果:
        </div>
    </form>
</body>
</html>

核心代码实际上就只有 body 标签中的 form 表单中的部分,但全部的 html 代码还是比较多的(相对而言)

// Servlet 程序
@WebServlet("/guess")
public class GuessNumber extends HttpServlet {
    private int toGuess = 0;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf8");
        Random random = new Random();
        toGuess = random.nextInt(100)+1;
        System.out.println("toGuess=" + toGuess);
        String html = "<!DOCTYPE html>\n" +
                "<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n" +
                "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
                "    <title>Document</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "    <form action=\"guess\" method=\"post\">\n" +
                "        <input type=\"text\" name=\"Num\">\n" +
                "        <input type=\"submit\" value=\"猜\">\n" +
                "        <div>\n" +
                "            结果:\n" +
                "        </div>\n" +
                "    </form>\n" +
                "</body>\n" +
                "</html>";
        resp.getWriter().write(html);//返回原始猜数字页面
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf8");
        int num = Integer.parseInt(req.getParameter("Num"));
        String str = ""; //结果直接拼接在要输出的 html 代码中
        if(num < toGuess) {
            str = "猜小了";
        }else if (num > toGuess) {
            str = "猜大了";
        }else {
            str = "猜对了";
        }
        String html = "<!DOCTYPE html>\n" +
                "<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n" +
                "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
                "    <title>Document</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "    <form action=\"guess\" method=\"post\">\n" +
                "        <input type=\"text\" name=\"Num\">\n" +
                "        <input type=\"submit\" value=\"猜\">\n" +
                "        <div>\n" +
                "            结果:\n" + str +
                "        </div>\n" +
                "    </form>\n" +
                "</body>\n" +
                "</html>";
        resp.getWriter().write(html);
    }
}

可明显的看出没有模板引擎时,长长的 html 代码和 java 代码都混杂在了一起 ,看起来极为不方便

2.2 模板引擎应用(猜数字)

模板引擎,正如其名,就是一个样板,上面扣除要动态替换的部分,用特殊符号进行占位,回头在 Servlet 代码中就可以使用这个模板,将要替换的内容进行替换。

类似于:

在这里插入图片描述

空白的熊猫头就是一个模板,在此基础上直接添加熊猫脸以及文字就可以完成一个熊猫头表情包,而不需要每次从零开始创造表情包。

模板引擎是由很多的,此次使用的是Thymeleaf

步骤一:

创建项目,目录结构之类的就而不多加介绍,请见详情链接

详情

步骤二:

引入依赖,需要引入两个依赖,一个是Servlet,一个是 Thymeleaf,在中央仓库中分别搜索这两个关键字,第一个就是,选择合适的版本,复制其中的代码片段到pom.xml

<dependencies>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf -->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf</artifactId>
        <version>3.0.15.RELEASE</version>
    </dependency>
</dependencies>

步骤三:

编写模板文件,将上面的猜数字 html 代码进行修改,具体就是将需要动态替换的信息用特殊符号进行占位

<body>
    <form action="guess" method="post">
        <input type="text" name="Num">
        <input type="submit" value="">
    </form>
    <div>
        结果:<span th:text="${result}"></span>
    </div>
</body>

此处需要动态替换的只有结果这里的显示,th:text="${result}就相当于模板引擎中的定义变量,此处定义的变量就是result,回头就可以在 java 代码中对该变量进行赋值,从而达到动态替换的结果。

对于正常的 html 代码来说是没有 th:text 这样的属性的,这是 Thymeleaf 扩充的属性,当其看见该属性就知道这里有需要被替换的部分。

将修改好的模板文件放在一个特殊目录下

在这里插入图片描述

步骤四:

编写 Servlet 代码

(1)针对 Thymeleaf 进行初始化,初始化代码都是固定套路,建议保存在什么地方,要用时直接复制粘贴

private TemplateEngine engine = new TemplateEngine();//1

@Override
public void init() throws ServletException {
    ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(getServletContext());//3
    resolver.setPrefix("/WEB-INF/template/");//4
    resolver.setSuffix(".html");//4
    resolver.setCharacterEncoding("utf-8");
    engine.setTemplateResolver(resolver);//5
}

(2)模板渲染具体操作

private int toGuess = 0; //需要被猜的数据
//处理 GET 请求操作,包含着生成随机数,以及返回猜数字原始页面
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setContentType("text/html;charset=utf-8");
    Random random = new Random();
    toGuess = random.nextInt(100)+1;
    System.out.println("toGuess = " + toGuess);
    WebContext webContext = new WebContext(req,resp,getServletContext());
    engine.process("GuessNum",webContext,resp.getWriter());
}
//处理 POST 请求,获取的 body 中的数据和 toGuess 进行比较,将结果替换到模板中 
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setContentType("text/html;charset=utf-8");
    int num = Integer.parseInt(req.getParameter("Num"));
    String result = "";
    if(num < toGuess) {
        result = "猜低了";
    }else if (num > toGuess) {
        result = "猜高了";
    }else {
        result = "猜对了";
    }
    WebContext webContext = new WebContext(req,resp,getServletContext());
    webContext.setVariable("result",result);
    //前面的"result"与th:text="${result}"中的要被替换的数据名相对应
    engine.process("GuessNum",webContext, resp.getWriter());
}

结果:

三、Thymeleaf 模板语法

在前面的用到的模板命令有 th:text ,实际上还有其他的用法

命令功能
th:text在标签体中展示表达式求值结果的文本内容
th:[HTML标签属性]设置任意的 HTML 标签属性的值
th:if当表达式的结果为真时则显示内容,否则不显示
th:each循环访问元素

设置标签文本:th:text

参考前面的 html 模板中的用法

设置标签属性:th:[HTML标签属性]

html 模板中有需要替换的链接

<a th:href="${url}">百度</a>

Servlet 代码中

webContext.setVariable("url", "http://www.baidu.com");

此时点击页面上点击 a 标签就可以跳转到 百度

条件判断:th:if

<div th:if="${!newGame}">
  <div>结果: <span th:text="${result}"></span> </div>
</div>

当 newGame 为假时,说明不需要重开一局,就继续将 result 的值进行替换

循环访问:th:each

用法:

th:each="自定义的元素变量名称 : ${集合变量名称}" 
<div th:each="message:${messages}">
    <span th:text="${message.from}"></span><span th:text="${message.to}"></span>
    说:
    <span th:text="${message.message}"></span>
</div>

messages 就是需要被替换的对象,java 代码里传过来Collections 类型对其进行替换,message 访问到 messages 中的每一个元素。下面的 th:text="${message.XX} 之类的对应的就是同样需要被替换的 message 变量中的各种属性

完!

举报

相关推荐

0 条评论