文章目录
1、模板技术
1.1 模板
-
模板引擎就是为了解决 HTML 和 Java 混在一起的问题。我们可以把 HTML 的内容提取出来, 放到单独的文件中, 称为模板。主要是处理 数据转化成为一些复杂格式的。
-
模板文件只是 web 应用生成资源的中间事务,不是真正的 web 资源。
-
SpringBoot 建议使用 Thymeleaf 作为默认模板。
-
优势:解耦数据和结构逻辑。
1.2 Thymeleaf 使用流程
1.2.1 添加依赖
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
1.2.2 在普通类中使用
package demo;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import java.util.Arrays;
import java.util.List;
public class ThymeleafDemo {
public static void main(String[] args) {
// 1、创建一个 模板引擎 对象
TemplateEngine engine = new TemplateEngine();
// 2、 创建一个 解析器 对象 ,对解析器进行必要的配置
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCharacterEncoding("utf-8");
resolver.setCacheable(false); // 渲染关闭
resolver.setPrefix("/templates/"); // 文件目录 类根路径下的 /templates/
resolver.setSuffix(".html"); // 文件后缀名
// 3、把解析器对象 关联到引擎对象中
engine.setTemplateResolver(resolver);
// 4.准备 Context 对象 , 添加需要渲染的数据
User user = new User();
user.uid = 199;
user.username = "cc";
user.password = "123456";
List<Integer> list = Arrays.asList(9, 8, 7, 6);
Context context = new Context();
context.setVariable("data", user);
context.setVariable("someString", "你好世界");
context.setVariable("numbers", list);
// 5、 传入模板名称 + context,进行 模板渲染
String result = engine.process("demo", context);
// 6、打印最终的字符串
System.out.println(result);
}
}
<!doctype html>
<html lang="zh-hans" xmlns::th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>模板技术演示</title>
</head>
<body>
<h1 th:text="'你好!' + ${data.username}"></h1>
<h2 th:text="${data.uid}">会被真实的 uid 替换</h2>
<h2 th:text="${data.password}"></h2>
</body>
</html>
- 在 Web 应用中有专门的模板,有个专门的解释器对象 ServletContext Resolver,有个专门的 Context 对象 WebContext 。
package com.cc.servlet;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import javax.servlet.ServletContext;
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.Arrays;
import java.util.List;
@WebServlet("/template-demo")
public class DemoTemplateServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
TemplateEngine engine = new TemplateEngine();
// Servlet 中的对象: 关于 Servlet 的上下文
ServletContext servletContext = req.getServletContext();
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(servletContext);
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCharacterEncoding("utf-8");
resolver.setPrefix("/WEB-INF/templates/");
resolver.setSuffix(".html");
resolver.setCacheable(false);
engine.setTemplateResolver(resolver);
WebContext webContext = new WebContext(req, resp, servletContext);
List<String> courseList = getCourseList();
webContext.setVariable("courseList",courseList);
String responseBody = engine.process("course-list", webContext);
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
resp.getWriter().println(responseBody);
}
private List<String> getCourseList() {
return Arrays.asList("JavaSE", "JavaDS", "JavaDB", "JavaWeb", "JavaTest", "JavaEE");
}
}
course-list.html
<!doctype html>
<html lang="zh-hans" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>课程列表</title>
</head>
<body>
<h1>Java 方向的课程列表</h1>
<ol>
<li th:each="course : ${courseList}" th:text="${course}"></li>
</ol>
</body>
</html>
1.2.3 模板对象和解析对象创建时机
1.2.3.1监听器模式
- 在 Servlet 运行过程中, 会有一些特殊的 “时机”, 可以供我们来执行一些我们自定义的逻辑.。监听器可以在这些特殊时机 “插入代码”。
- 例如注册场景:注册用户----》根据用户的不同地域生成不同的标签----》给用户发送通知等等,经过监视器改造后,只关注核心流程,发布事件。
1.2.3.2 创建时机
- 在 ServletContext 刚好被初始化的时机下,执行我们的模板初始化,由于 ServletContext 只会被初始化一次,所以模板初始化工作也只执行一次。
- 1、添加 @WebListener,代表写的类是一个监听器类。
- 2、实现 ServletContextListener 接口,ServletContext 初始化和销毁的事件。
- 3、优化:重写 contextlnitialized 方法,在 ServletContext 初始化后执行一些代码。
package com.cc.servlet;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import javax.servlet.ServletContext;
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.Arrays;
import java.util.List;
//@WebServlet("/template-demo")
public class TemplateDemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 创建模板引擎对象
TemplateEngine engine = new TemplateEngine();
ServletContext servletContext = req.getServletContext();
// 2. 创建解析器对象
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(servletContext);
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCharacterEncoding("utf-8");
resolver.setPrefix("/WEB-INF/templates/");
resolver.setSuffix(".html");
resolver.setCacheable(false);
// 3. 关联解析器对象到引擎对象上
engine.setTemplateResolver(resolver);
}
}
package com.cc.servlet;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import javax.servlet.ServletContext;
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.Arrays;
import java.util.List;
@WebServlet("/template")
public class TemplateServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = req.getServletContext();
// 4. 提供给模板引擎本次解析的上下文对象
WebContext webContext = new WebContext(req, resp, servletContext);
// 5. 准备好要放入 Context 的数据
List<String> courseList = getCourseList();
webContext.setVariable("courseList", courseList);
// 6. 通过模板引擎生成最终的正文内容
// 3.5 从 ServletContext 对象中取出来之前放进去的 engine 对象
TemplateEngine engine = (TemplateEngine) servletContext.getAttribute("engine");
String responseBody = engine.process("course-list", webContext);
// 7. 填充响应对象
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
resp.getWriter().println(responseBody);
}
private List<String> getCourseList() {
return Arrays.asList("JavaSE", "JavaDS", "JavaDB", "JavaWeb", "JavaTest", "JavaEE");
}
}