当前位置:网站首页>ThymeleafEngine模板引擎
ThymeleafEngine模板引擎
2022-06-11 05:52:00 【霸王龙骨架带走渡渡鸟】
目录
动态页面的渲染方式
动态页面需要通过服务器根据客户端传来的参数, 动态计算得到一些结果, 并且把这些结果显示到页面上.
服务器渲染

数据和页面结合的工作, 通过服务器完成.
客户端渲染

服务器把数据返回给浏览器, 由浏览器把数据和页面结合起来.
浏览器和服务器之间的数据往往交互通过 ajax 进行, 数据的格式往往使用 JSON.
字符串拼接HTML
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;
@WebServlet("/html")
public class HtmlServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
//请求传过来一个query string,里面有一个参数是name,返回的页面里,就有这个name的值,请求的name不同,返回的页面就不同
String name = req.getParameter("name");
resp.getWriter().write("<h3>"+name+"</h3");
}
}如果是返回一个简单的页面, 可以按照上述方式拼接字符串完成.
但是如果是一个复杂的页面, 就要写很复杂的代码了
使用模板引擎
模板引擎使用流程
通过maven引入依赖

选择3.0.12版本
创建HTML模板文件

hello.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>thymeleaf</title>
</head>
<body>
<!--th就是thymeleaf的缩写,表示这个属性是thymeleaf类提供的,text表示类型为字符串-->
<h3 th:text="${message}"></h3>
</body>
</html>编写Servlet代码
helloThymeleafServlet.java
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;
@WebServlet("/helloThymeleaf")
public class HelloThymeleafServlet extends HttpServlet {
//这是Thymeleaf中最核心的类 TemplateEngine模板引擎
private TemplateEngine engine = new TemplateEngine();
@Override
public void init() throws ServletException {
//创建一个模板解析器对象,搭配上下文来使用
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(this.getServletContext());
//让模板解析器来加载模板文件,这里的前缀就表示模板文件所在的目录,正因为如此,模板文件就必须放在WEB-INF中
//设置前缀后缀,让模板引擎知道要加载哪些文件到内存中,以备后用
resolver.setPrefix("/WEB-INF/template/");
resolver.setSuffix(".html");
resolver.setCharacterEncoding("utf-8");
//把解析器对象,设置到engine中
engine.setTemplateResolver(resolver);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//初始化之后,就要执行模板渲染了
//1.先从参数中读取出用户要传过来的message的值
String message = req.getParameter("message");
//2.把当前请求中读取出来的message的值和模板中的${message}关联起来
WebContext webContext = new WebContext(req,resp,this.getServletContext());
webContext.setVariable("message",message);
//3.进行最终渲染,将webContext的内容替换到hello
String html = engine.process("hello",webContext);
System.out.println(html);
resp.getWriter().write(html);
}
}部署程序

可以看到

Thymeleaf模板语法

设置标签文本
th:text 的功能就是能设置标签的文本内容.
设置标签属性
一些常用的需要设置的属性:href src class style ......
<a th:href="${url1}">百度</a>
<a th:href="${url2}">搜狗</a>条件判断
th:if 的功能是根据条件决定该标签是否显示.
<div th:if="${!newGame}">
<div>已经猜了: <span th:text="${count}"></span> 次</div>
<div>结果: <span th:text="${result}"></span> </div>
</div>循环
th:each 的功能是可以循环的构造出多个元素.
在java代码中就是用类存储person,用list存储presons
<ul>
<li th:each="person : ${persons}">
<span th:text="${person.name}"></span>
<span th:text="${person.phone}"></span>
</li>
</ul>查看模板语法的报错信息
通过形如下面的代码来渲染模板, 如果模板渲染出错, 能看到服务器返回了 500 状态码, 但是看不到异常调用栈.
engine.process("thymeleafEach", webContext, resp.getWriter());原因是抛出的异常被 process 内部处理掉了.
可以使用以下代码代替, 即可看到异常调用栈.
String html = engine.process("thymeleafEach", webContext);
resp.getWriter().write(html);只创建一个引擎实例
什么是ServletContext

是为了让webapp的多个Servlet之间能够共享数据

先访问writer,给message写数据
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;
//负责像ServletContext里面写数据
//例如通过/writer?message=aaa访问到WriterServlet,就把message=aaa这个键值对存到ServletContext
@WebServlet("/writer")
public class WriterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
//1.从请求中获取到message参数
String message = req.getParameter("message");
//2.取出ServletContext对象(这个对象是Tomcat在加载webapp的时候自动创建的)
ServletContext context = this.getServletContext();
//3.往这里写入键值对
context.setAttribute("message",message);
//4.返回响应
resp.getWriter().write("<h3>存储message成功</h3>");
}
}再访问reader,就能拿到message的数据
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;
//使用Servlet从ServletContext中读取数据
//从WriterServlet里面存的数据中取出来
@WebServlet("/reader")
public class ReaderServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
//1.获取到同一个ServletContext对象
ServletContext context = this.getServletContext();
//2.从Context中获取到刚才存的值
String message = (String) context.getAttribute("message");
//3.把取出的数据显示出来
resp.getWriter().write("message: " + message);
}
}什么是监听器Listener
可以看到,刚才的两个类中的ServletContext对象是同一个,所以我们需要使用ServletContext来存储一个TemplateEngine对象,达到让当前webapp的所有Servlet共同使用同一个TemplateEngine。
就可以再ServletContext创建好之后,第一时间给TemplateEngine进行初始化,为了达到这一目的,Servlet给我们提供了一个机制,Listener监听器,因此就可以使用Listener来监听ServletContext的初始化完毕操作
Servlet 中的监听器种类有很多:
监听 HttpSession 的创建销毁, 属性变化
监听 HttpServletRequest 的创建销毁, 属性变化
监听 ServletContext 的创建销毁, 属性变化
此处我们只需要使用监听器监听 ServletContext 的创建即可.
涉及到的接口: ServletContextListener
我们实现这个接口, 并重写其中的 servletContextInitialized 方法. 当 ServletContext 创建的时候就会自动执行到 servletContextInitialized 方法
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
//需要让Tomcat识别这个类,所以要加WebListener这个注解
@WebListener
public class MyListener implements ServletContextListener {
//初始化完毕后会执行这个方法
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext初始化");
//获取一下ServletContext对象,通过方法和参数获取到的
ServletContext context = sce.getServletContext();
context.setAttribute("message","初始化的消息");
}
//销毁之前执行这个方法
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}效果

修改Thymeleaf引擎初始化代码
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ThymeleafConfig implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//初始化TemplateEngine
ServletContext context = sce.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.setTemplateResolver(resolver);
//3.把创建好的engine实例放到ServletContext中
context.setAttribute("engine",engine);
System.out.println("TemplateEngine初始化");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}边栏推荐
- 获取程序exit的值
- JS -- reference type
- Multithreading tutorial (XXI) double checked locking problem
- After adding the header layout to the recyclerview, use the adapter Notifyitemchanged (POS,'test') invalid local refresh
- Vscode plug-in development
- The meaning in the status column displayed by PS aux command
- Flask develops and implements the like comment module of the online question and answer system
- Delegation agreement, data source agreement and advanced view in view
- Write a list with kotlin
- NDK learning notes (IX) POSIX sockect connection oriented communication
猜你喜欢

What do you need to know about Amazon evaluation?

NDK learning notes (14) create an avi video player using avilib+window

Getbackgroundaudiomanager controls music playback (dynamic binding of class name)

Error:Execution failed for task ':app:buildNative'. & gt; A problem occurred'x/x/x/'NDK build' error resolution

初步了解多任务学习

Exploration of kangaroo cloud data stack on spark SQL optimization based on CBO

NFC Development -- utility tools and development documents (IV)

Getting started with kotlin

What should the cross-border e-commerce evaluation team do?

数据接入平台方案实现(游族网络)
随机推荐
After adding the header layout to the recyclerview, use the adapter Notifyitemchanged (POS,'test') invalid local refresh
使用Batch读取注册表
NDK R21 compiles ffmpeg 4.2.2 (x86, x86_64, armv7, armv8)
数组部分方法
11. Gesture recognition
handler
Multi threading tutorial (XXIV) cas+volatile
What should the cross-border e-commerce evaluation team do?
Do we really need conference headphones?
Elk log system practice (VI): comparison between vector and filebeat for technology selection
JS -- reference type
SwiftUI: Navigation all know
More than 20 cloud collaboration functions, 3 minutes to talk through the enterprise's data security experience
Recursively process data accumulation
SQLite one line SQL implementation updates if there is one, inserts if there is none, multiple conditions, complex conditions
Metabase源码二次开发之Clojure 安装
OJDBC在Linux系统下Connection速度慢解决方案
使用Batch枚舉文件
View controller and navigation mode
NDK learning notes (VIII) thread related