模板引擎
- 1 关于动态页面的渲染
- 2 非模板引擎的弊端
- 3 模板引擎
-
- 3.1 什么是模板引擎?
- 3.2 Thymeleaf 语法
- 3.3 模板引擎的使用
- 4 总结
1 关于动态页面的渲染
渲染就是把数据和页面进行结合起来, 主要分为服务器渲染和客户端渲染两种方式. 如下图所示:
服务器渲染指的是数据和页面的结合工作由服务器来完成;
客户端渲染指的是服务器将数据返回给浏览器,由浏览器将数据和页面进行结合, 通常是用 ajax 进行交互.
2 非模板引擎的弊端
简单说一下其弊端,例如用字符串来拼接一个 html 页面,如下所示:
@WebServlet("/html")
public class HtmlServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String sex = req.getParameter("sex");
String nickname = req.getParameter("nickname");
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().write("<h3> name: " + name + "<h3>");
resp.getWriter().write("<h3> sex: " + sex + "<h3>");
resp.getWriter().write("<h3> nickname: " + nickname + "<h3>");
}
}
通过 query string 来写入参数传过来后, 返回的页面中就包含了 query string 中的值.但是我们再看这段代码,非常简单地界面还可以,稍微复杂点的界面想要通过这种方式来实现就会特别麻烦,例如像 CSDN 我们点开的任何一个页面,于是就有了模板引擎的出现.
3 模板引擎
3.1 什么是模板引擎?
模板引擎指的是我们单独写一个固定的 html 页面, 这里写好之后就固定不动了, 然后不固定的,动态变化的字段使用特殊符号进行占位, 当程序跑起来后, 不固定的地方得以替换. 例如 印象笔记这个软件就有模板这个功能, 我们在使用这个模板的时候, 只需要往里面套文字即可, 大大减少了使用者的工作量, 非常便捷, 那么模板引擎就有这样的功能.
Java 模板引擎非常之多, 但大都大同小异, 这里我们以 Thymeleaf 为例进行简单演示使用流程.
3.2 Thymeleaf 语法
- th:text : 在标签体中展示表达式求值结果的文本内容, 下面的代码中有示例;
- th:each : 循环访问元素, 下面的代码中有示例;
- th:[HTML 标签属] : 设置任意的 HTML 标签属性的值, 属性有很多,例如 href, src 等等;
- th:if : 当表达式的结果为真时则显示内容, 否则不显示.
3.3 模板引擎的使用
- 步骤一: 在 pom.xml 中引入依赖, 我们还是从中央仓库中查找;
- 步骤二: 编写一个 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=\, initial-scale=1.0">
<title>电话本</title>
</head>
<body>
<ul>
<li th:each="person : ${persons}">
<span th:text="${person.name}"></span>
<span th:text="${person.phone}"></span>
</li>
</ul>
</body>
</html>
代码解读:
th: 就是 thymeleaf 的缩写, 指的是这个属性由 thymeleaf 来提供;
${person.name}: 这就是一个具体的变量, 也就是上文中所说的不固定的部分, 就可以实现动态的变换.
- 步骤三: 初始化模板引擎
@WebListener
public class ThymeleafConfig implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
// 初始化 TemplateEngine
ServletContext context = servletContextEvent.getServletContext();
// 1. 创建 engine 实例
TemplateEngine engine = new TemplateEngine();
// 2. 创建 resolver 实例
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(context);
resolver.setPrefix("/WEB-INF/template/");
resolver.setSuffix(".html");
resolver.setCharacterEncoding("utf-8");
// 将 engine 和 resolver 关联起来
engine.setTemplateResolver(resolver);
// 3. 把创建好的 engine 实例给放到 ServletContext 中
context.setAttribute("engine",engine);
System.out.println("TemplateEngine 初始化完毕!");
}
}
代码解读:
@WebListener: 加这个目的是为了让 Tomcat 能够识别到这个类;
TemplateEngine: Template 模板的意思, Engine 引擎的意思; 这个类是 Thymeleaf 的核心类, 用于完成最终页面的渲染工作;
ServletContextTemplateResolver: 创建一个模板解析器对象, 搭配 ServletContext 来使用, 也就是将之前写好的 HTML 模板加载过来, 并告知 engine;
总之, ServletContext 创建的对象存在的意义就是多个 Servlet 之间能够共享数据; 关于 ServletContext 的使用如下:
- void setAttribute(String name, Object obj): 设置属性(键值对);
- Object getAttribute(String name): 根据属性名获取属性值, 如果那么不存在就返回 null;
- void removeAttribute(String name): 删除对应的属性.
- 步骤四: 编写 Servlet 代码;
class Person {
public String name;
public String phone;
public Person(String name, String phone) {
this.name = name;
this.phone = phone;
}
}
@WebServlet("/each")
public class EachServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=utf-8");
List<Person> persons = new ArrayList<>();
persons.add(new Person("Lee", "110"));
persons.add(new Person("Mee", "111"));
persons.add(new Person("Nee", "112"));
WebContext webContext = new WebContext(req,resp,getServletContext());
webContext.setVariable("persons", persons);
// 初始化模板引擎
TemplateEngine engine = (TemplateEngine) getServletContext().getAttribute("engine");
String html = engine.process("thymeleafEach", webContext);
resp.getWriter().write(html);
}
}
代码解读:
WebContext: WebContext 对象里面主要包含要渲染的变量有哪些, 以及变量的值是什么; 就是一个键值对结构, 目的是将 ${persons} 与 java 中的 persons 关联起来, 将模板中的 persons 变量渲染成 persons 的值; 也就是将 HTML 模板中的变量和 java 代码中的变量给关联起来;
engine.process(“thymeleafEach”, webContext):
- 步骤五: 运行结果:
4 总结
总结 模板引擎 的使用流程:
- 1 先编写 HTML 模板并放到指定目录中;
- 2 初始化模板引擎
2.1: 创建 Context 对象;
2.2: 创建 TemplateEngine 实例;
2.3:创建 ServletContextTemplateResolver 实例;
2.4: 关联 engine 和 resolver;
2.5: 将创建好的 engine 实例放到 Context 对象中; - 3 创建 Servlet 类并编写相关代码
3.1: WebContext 使得 HTML 模板中的变量与 Servlet 中的变量进行关联;
3.2: 初始化操作;
3.3: TemplateEngine 中的 process 方法来进行渲染.