0


模板引擎认识

文章目录

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

服务器生成动态页面有两种方式:

服务器渲染

客户端渲染

服务器渲染

特点:

  1. 服务器会向客户端返回一个完整的 html 页面
  2. html 中的一些会动态变化的数据通过“模板引擎”的方式进行动态替换

优点:

  1. 前后端交互的次数少,一次 HTTP请求/响应就可以获取到一个完整的 html 文件,效率高

缺点:

  1. 前后端代码无法充分解耦合。在正式工作中该方法会运用的比较少,需要前后端开发人员一起配合着开发,分工不够明确,也没有办法独立测试

客户端渲染

特点:

  1. 也叫前后端分离客户端通过ajax的方式和服务器进行交互
  2. 服务器返回的就只是单纯的数据,数据大多以JSON的方式进行组织

优点:

  1. 前后端代码充分解耦合。前后端开发人员可以各自开发各自的,通过一些测试工具对各自代码进行测试(比如后端的 Postman,前端的 mock server)

缺点:

  1. 前后端交互的次数较多,需要多组 ajax 才能获取到一个完整的数据,效率相较服务器渲染来说较低,但因其优点较好,这点缺点不算啥。

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

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")publicclassGuessNumberextendsHttpServlet{privateint toGuess =0;@OverrideprotectedvoiddoGet(HttpServletRequest req,HttpServletResponse resp)throwsServletException,IOException{
        resp.setContentType("text/html;charset=utf8");Random random =newRandom();
        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);//返回原始猜数字页面}@OverrideprotectedvoiddoPost(HttpServletRequest req,HttpServletResponse resp)throwsServletException,IOException{
        resp.setContentType("text/html;charset=utf8");int num =Integer.parseInt(req.getParameter("Num"));String str ="";//结果直接拼接在要输出的 html 代码中if(num < toGuess){
            str ="猜小了";}elseif(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><formaction="guess"method="post"><inputtype="text"name="Num"><inputtype="submit"value="猜"></form><div>
        结果:<spanth:text="${result}"></span></div></body>

此处需要动态替换的只有结果这里的显示,

th:text="${result}

就相当于模板引擎中的定义变量,此处定义的变量就是

result

,回头就可以在 java 代码中对该变量进行赋值,从而达到动态替换的结果。

对于正常的 html 代码来说是没有 th:text 这样的属性的,这是

Thymeleaf 扩充的属性

,当其看见该属性就知道这里有需要被替换的部分。

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

在这里插入图片描述

步骤四:

编写 Servlet 代码

(1)针对

Thymeleaf 进行初始化

,初始化代码都是固定套路,建议保存在什么地方,要用时直接复制粘贴

privateTemplateEngine engine =newTemplateEngine();//1@Overridepublicvoidinit()throwsServletException{ServletContextTemplateResolver resolver =newServletContextTemplateResolver(getServletContext());//3
    resolver.setPrefix("/WEB-INF/template/");//4
    resolver.setSuffix(".html");//4
    resolver.setCharacterEncoding("utf-8");
    engine.setTemplateResolver(resolver);//5}
  1. 首先创建一个 TemplateEngine 对象, Template: 模板, Engine: 引擎。这个类是 Thymeleaf 的核心类, 用于完成最终的页面渲染工作(替换数据)
  2. 在这个 Servlet 被加载的时候, 会被调用一次init()方法, Thymeleaf 的初始化就适合放在 init() 方法中
  3. 创建一个 ServletContextTemplateResolver对象。 resolver: 解析器。 这个对象的功能是从磁盘上加载 html 模板文件。后面的参数 getServletContext()就是获得上下文对象,每个 webapp都有一个自己的上下文对象(ServletContext),归当前 webapp所有 Servlet 共用,可以基于这个在多个 Servlet 之间传递数据
  4. 接下来就针对 resolver 对象来设置一些属性。setPrefix()setSuffix()来指定哪些文件被视为模板文件, 需要被加载,前者表文件前缀,后者表文件后缀。注意其中的写法,加载目录不可以少一个’/’。setCharacterEncoding()设置字符集
  5. 把解析器对象和 TemplateEngine对象关联起来. 后面 TemplateEngine 进行具体渲染。工作时, 就需要先获取到刚刚解析好的模板.

(2)模板渲染具体操作

privateint toGuess =0;//需要被猜的数据//处理 GET 请求操作,包含着生成随机数,以及返回猜数字原始页面@OverrideprotectedvoiddoGet(HttpServletRequest req,HttpServletResponse resp)throwsServletException,IOException{
    resp.setContentType("text/html;charset=utf-8");Random random =newRandom();
    toGuess = random.nextInt(100)+1;System.out.println("toGuess = "+ toGuess);WebContext webContext =newWebContext(req,resp,getServletContext());
    engine.process("GuessNum",webContext,resp.getWriter());}//处理 POST 请求,获取的 body 中的数据和 toGuess 进行比较,将结果替换到模板中 @OverrideprotectedvoiddoPost(HttpServletRequest req,HttpServletResponse resp)throwsServletException,IOException{
    resp.setContentType("text/html;charset=utf-8");int num =Integer.parseInt(req.getParameter("Num"));String result ="";if(num < toGuess){
        result ="猜低了";}elseif(num > toGuess){
        result ="猜高了";}else{
        result ="猜对了";}WebContext webContext =newWebContext(req,resp,getServletContext());
    webContext.setVariable("result",result);//前面的"result"与th:text="${result}"中的要被替换的数据名相对应
    engine.process("GuessNum",webContext, resp.getWriter());}
  1. WebContext 对象用来组织要渲染的数据,实际上就是一个键值对结构(hash 表),记住这里面的三个参数。
  2. 通过 setVariable() 方法向 hash 表中插入键值对,个模板中可以存在多个占位符,可以通过该方法设置多个变量。在 处理 POST 请求中就需要将生成的 result 给填充到 html 中的<span th:text="${result}"></span>中。一
  3. engine.process来进行具体的渲染工作.。这个操作会把具体的模板文 件, 和要渲染的数据关联起来, 并把最终结果写入到 resp 对象。第一个参数就是 html 模板的文件名,后俩参数是不变的。

结果:

在这里插入图片描述

三、Thymeleaf 模板语法

在前面的用到的模板命令有 th:text ,实际上还有其他的用法
命令功能th:text在标签体中展示表达式求值结果的文本内容th:[HTML标签属性]设置任意的 HTML 标签属性的值th:if当表达式的结果为真时则显示内容,否则不显示th:each循环访问元素
设置标签文本:th:text

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

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

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

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

Servlet 代码中

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

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

条件判断:th:if

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

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

循环访问:th:each

用法:

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

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

完!

标签: tomcat java 服务器

本文转载自: https://blog.csdn.net/weixin_46103589/article/details/123792543
版权归原作者 富春山居_ZYY 所有, 如有侵权,请联系我们删除。

“模板引擎认识”的评论:

还没有评论