Thymeleaf
⽤Thymeleaf
: 20181029 - 2018年10⽉29⽇
: 3.0.11.RELEASE
: https ://www.thymeleaf.org
教
程
:
使
⽂
件
版
本
项
⽬
版
本
项
⽬
⽹
站
1介
绍Thymeleaf
1.1什
是Thymeleaf?
Thymeleaf是
Thymeleaf的
端Java模
于Web和
理HTML,XML,JavaScript,CSS甚
Thymeleaf也
了Web标
准 - 特
是HTML5 - 允
1.2 Thymeleaf过
,Thymeleaf允
HTML
XML
JAVASCRIPT
CSS
( HTML 和 XML )
( TEXT , JAVASCRIPT 和 CSS )
( RAW )
该HTML模
的HTML的
括HTML5,HTML4和XHTML。
码/结
该XML模
许XML输
的 - 没
对DTD或XML架
该TEXT模
XML模
该JAVASCRIPT模
JavaScript⽂
理 TEXT ,
,DOCTYPE,
在Thymeleaf应
的JavaScript⽂
于JavaScript的
的 TEXT 模
与HTML⽂
该 JAVASCRIPT 模
等 - 如
,HTML或
该CSS模
与Thymeleaf应
⽤CSS⽂
与 JAVASCRIPT 模
, CSS 模
⽤ TEXT
该RAW模
1.3⽅
Thymeleaf是
,URL响
,HTML格
何Thymeleaf代
合 - 加
件 - 是
,Thymeleaf的
么
⼀
个
现
代
服
务
器
板
引
擎
,
适
⽤
独
⽴
环
境
,
能
够
处
⾄
纯
⽂
本
。
主
要
⽬
标
是
提
供
⼀
种
优
雅
且
⾼
度
可
维
护
的
模
板
创
建
⽅
式
。
为
实
现
这
⼀
⽬
标
,
它
以
⾃
然
模
板
的
概
念
为
基
础
,
将
其
逻
辑
注
⼊
模
板
⽂
件
,
其
⽅
式
不
会
影
响
模
板
被
⽤
作
设
计
原
型
。
这
改
善
了
设
计
沟
通
,
缩
⼩
了
设
计
和
开
发
团
队
之
间
的
差
距
。
从
⼀
开
始
就
设
计
别
许
您
创
建
完
全
验
证
的
模
板
,
如
果
您
需
要
的
话
。
程
可
以
使
⽤
哪
种
模
板
?
开
箱
即
⽤
许
您
处
理
六
种
模
板
,
每
种
模
板
称
为
模
板
模
式
:
⽂
本
⽣
的
有
两
种
标
记
模
板
模
式
,
三
种
⽂
本
模
板
模
式
和
⼀
种
⽆
操
作
模
板
模
式
。
板
模
式
将
允
许
任
何
类
型
输
⼊
,
包
不
会
执
⾏
验
证
或
格
式
良
好
检
查
,
并
且
将
在
输
出
中
尽
可
能
地
尊
重
模
板
代
构
。
板
模
式
将
允
⼊
。
在
这
种
情
况
下
,
代
码
应
该
是
格
式
良
好
有
未
封
闭
的
标
签
,
没
有
不
带
引
号
的
属
性
等
果
发
现
格
式
错
误
,
解
析
器
将
抛
出
异
常
。
请
注
意
,
不
会
执
⾏
验
证
(
针
构
)
。
板
模
式
将
允
许
⾮
标
记
性
质
的
模
板
使
⽤
特
殊
的
语
法
。
此
类
模
板
的
⽰
例
可
能
是
⽂
本
电
⼦
邮
件
或
模
板
⽂
档
。
请
注
意
板
也
可
以
被
处
在
这
种
情
况
下
,
它
们
不
会
被
解
析
为
标
记
,
并
且
每
个
标
记
注
释
等
都
将
被
视
为
纯
⽂
本
。
板
模
式
将
允
许
⽤
程
序
件
的
处
理
。
这
意
味
着
能
够
以
件
相
同
的
⽅
式
在
件
中
使
⽤
模
型
数
据
,
但
是
使
⽤
特
定
集
成
,
例
如
专
⻔
的
转
义
或
⾃
然
脚
本
。
板
模
式
被
认
为
是
⼀
种
⽂
本
模
式
,
因
此
使
⽤
相
同
的
特
殊
语
法
板
模
式
。
板
模
式
将
允
许
参
件
的
处
理
。
式
类
似
板
模
式
也
是
⽂
本
模
式
,
并
使
模
板
模
式
中
的
特
殊
处
理
语
法
。
板
模
式
将
根
本
不
处
理
模
板
。
它
⽤
于
将
未
经
处
理
的
资
源
(
⽂
件
应
等
)
插
⼊
到
正
在
处
理
的
模
板
中
。
例
如
式
的
外
部
⾮
受
控
资
源
可
以
包
含
在
应
⽤
程
序
模
板
中
,
安
全
地
知
道
这
些
资
源
可
能
包
含
的
任
码
都
不
会
被
执
⾏
。
⾔
:
标
准
⽅
⾔
⼀
个
极
易
扩
展
的
模
板
引
擎
(
实
际
上
它
可
以
称
为
模
板
引
擎
框
架
)
,
允
许
您
定
义
和
⾃
定
义
模
板
处
理
的
细
节
级
别
。
将
⼀
些
逻
辑
应
⽤
于
标
记
⼯
件
(
标
签
,
某
些
⽂
本
,
注
释
或
仅
仅
是
占
位
符
,
如
果
模
板
不
是
标
记
)
的
对
象
称
为
处
理
器
,
这
些
处
理
器
的
集
上
可
能
还
有
⼀
些
额
外
的
⼯
什
么
⼀
个
⽅
⾔
通
常
是
由
。
开
箱
即
⽤
核
⼼
库
提
供
了
⼀
种
称
为
标
准
⽅
⾔
的
⽅
⾔
,
对
⼤
多
数
⽤
⼾
来
说
应
该
⾜
够
了
。
请
注
意
,
⽅
⾔
实
际
上
可
以
没
有
处
理
器
,
并
且
完
全
由
其
他
类
型
的
⼯
件
组
成
,
但
处
理
器
绝
对
是
最
常
⻅
的
⽤
例
。
Thymeleaf也
的thymeleaf-spring3和thymeleaf-spring4集
为“SpringStandard⽅
⾔”的
OGNL)
⽤Spring框
是Spring MVC⽤
) ,
⽤Spring Expression Language或SpringEL代
在Spring应
的JSP可
⽰HTML模
...... Thymeleaf Standard Dialect将
由 ${user.name} 在
为“James Carrot”)
本
教
程
涵
盖
标
准
⽅
⾔
。
您
将
在
以
下
⻚
⾯
中
了
解
的
每
个
属
性
和
语
法
功
能
都
由
此
⽅
⾔
定
义
,
即
使
未
明
确
提
及
。
当
然
,
如
果
⽤
⼾
希
望
在
利
⽤
库
的
⾼
级
功
能
的
同
时
定
义
⾃
⼰
的
处
理
逻
辑
,
则
可
以
创
建
⾃
⼰
的
⽅
⾔
(
甚
⾄
扩
展
标
准
⽅
⾔
)
。
可
以
配
置
为
⼀
次
使
⽤
多
种
⽅
⾔
。
官
⽅
成
包
都
定
义
了
⼀
种
称
⽅
⾔
,
它
与
标
准
⽅
⾔
⼤
致
相
同
,
但
是
为
了
更
好
地
利
架
中
的
某
些
功
能
(
例
如
使
替
。
因
此
,
如
果
您
⼾
,
那
么
您
不
会
浪
费
时
间
,
因
为
您
在
此
处
学
习
的
⼏
乎
所
有
内
容
都
将
⽤
程
序
中
使
⽤
。
标
准
⽅
⾔
的
⼤
多
数
处
理
器
都
是
属
性
处
理
器
。
这
使
得
浏
览
器
甚
⾄
可
以
在
处
理
之
前
正
确
显
板
⽂
件
,
因
为
它
们
只
会
忽
略
其
他
属
性
。
例
如
,
虽
然
使
⽤
标
记
库
能
包
含
不
能
由
浏
览
器
直
接
显
⽰
的
代
码
⽚
段
,
例
如
:
允
许
我
们
实
现
相
同
的
功
能
:
这
不
仅
可
以
被
浏
览
器
正
确
显
⽰
,
⽽
且
还
允
许
我
们
(
可
选
地
)
在
其
中
指
定
值
属
性
(
在
这
种
情
况
下
,
当
在
浏
览
器
中
静
态
打
开
原
型
时
将
显
⽰
该
属
性
,
并
且
这
将
处
理
模
板
期
间
评
估
得
到
的
值
代
替
。
这
有
助
于
您
的
设
计
⼈
员
和
开
发
⼈
员
处
理
相
同
的
模
板
⽂
件
,
并
减
少
将
静
态
原
型
转
换
为
⼯
作
模
板
⽂
件
所
需
的
⼯
作
量
。
执
⾏
此
操
作
的
能
⼒
是
称
为
⾃
然
模
板
的
功
能
。
2 The Good Thymes虚
在Good Thymes Virtual Grocery GitHub存
2.1杂
⽤Thymeleaf处
Customers Orders Comments Products
⽰Thymeleaf的
建 Products 销
由 Service 包
public class ProductService {
...
public List
findAll() {
return ProductRepository.getInstance().findAll();
}
public Product findById(Integer id) {
return ProductRepository.getInstance().findById(id);
拟
杂
货
店
可
以
储
库
中
找
到
本
指
南
的
本
章
和
后
续
章
节
中
显
⽰
的
⽰
例
的
源
代
码
。
货
店
的
⽹
站
为
了
更
好
地
解
释
使
理
模
板
所
涉
及
的
概
念
,
本
教
程
将
使
⽤
可
从
项
⽬
⽹
站
下
载
的
演
⽰
应
⽤
程
序
。
这
个
应
⽤
程
序
是
⼀
个
假
想
的
虚
拟
杂
货
的
⽹
站
,
并
将
为
我
们
提
供
许
多
场
景
来
展
许
多
功
能
。
⾸
先
,
我
们
需
要
⼀
套
简
单
的
模
型
实
体
⽤
于
我
们
的
应
⽤
程
序
:
通
过
创
售
。
我
们
还
将
管
理
这
些
:
⽰
例
应
⽤
程
序
模
型
我
们
的
应
⽤
程
序
还
有
⼀
个
⾮
常
简
单
的
服
务
层
,
含
以
下
⽅
法
的
对
象
组
成
:
}
}
在Web层
求URL将
⽤Thymeleaf的
private boolean process(HttpServletRequest request, HttpServletResponse response)
throws ServletException {
try {
// This prevents triggering engine executions for resource URLs
if (request.getRequestURI().startsWith("/css") ||
request.getRequestURI().startsWith("/images") ||
request.getRequestURI().startsWith("/favicon")) {
return false;
}
/*
* Query controller/URL mapping and obtain the controller
* that will process the request. If no controller is available,
* return false and let other filters/servlets process the request.
*/
IGTVGController controller = this.application.resolveControllerForRequest(request);
if (controller == null) {
return false;
}
/*
* Obtain the TemplateEngine instance.
*/
ITemplateEngine templateEngine = this.application.getTemplateEngine();
/*
* Write the response headers
*/
response.setContentType("text/html;charset=UTF-8");
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
/*
* Execute the controller and process view template,
* writing the results to the response writer.
*/
controller.process(
request, response, this.servletContext, templateEngine);
return true;
} catch (Exception e) {
try {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final IOException ignored) {
// Just ignore this
}
throw new ServletException(e);
}
}
的 IGTVGController 界
public interface IGTVGController {
,
我
们
的
应
⽤
程
序
将
有
⼀
个
过
滤
器
,
它
将
根
据
请
执
⾏
委
托
给
启
命
令
:
这
是
我
们
⾯
:
public void process(
HttpServletRequest request, HttpServletResponse response,
ServletContext servletContext, ITemplateEngine templateEngine);
}
建 IGTVGController 接
⽤ ITemplateEngine 对
2.2创
的process(...)
ITemplateEngine templateEngine = this.application.getTemplateEngine();
着GTVGApplication类
置Thymeleaf应
: TemplateEngine 实
( ITemplateEngine 接
的 org.thymeleaf.TemplateEngine 对
public class GTVGApplication {
...
private final TemplateEngine templateEngine;
...
public GTVGApplication(final ServletContext servletContext) {
super();
ServletContextTemplateResolver templateResolver =
new ServletContextTemplateResolver(servletContext);
// HTML is the default mode, but we set it anyway for better understanding of code
templateResolver.setTemplateMode(TemplateMode.HTML);
// This will convert "home" to "/WEB-INF/templates/home.html"
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
我
们
现
在
要
做
的
就
是
创
⼝
的
实
现
,
从
服
务
中
检
索
数
据
并
使
象
处
理
模
板
。
最
后
,
它
看
起
来
像
这
样
:
⽰
例
应
⽤
程
序
主
⻚
但
⾸
先
让
我
们
看
看
该
模
板
引
擎
是
如
何
初
始
化
的
。
建
和
配
置
模
板
引
擎
我
们
的
过
滤
器
中
⽅
法
包
含
以
下
⾏
:
这
意
味
负
责
创
建
和
配
⽤
程
序
中
最
重
要
的
对
象
之
⼀
例
⼝
的
实
现
)
。
我
们
象
初
始
化
如
下
:
// Template cache TTL=1h. If not set, entries would be cached until expelled
templateResolver.setCacheTTLMs(Long.valueOf(3600000L));
// Cache is set to true by default. Set to false if you want templates to
// be automatically updated when modified.
templateResolver.setCacheable(true);
this.templateEngine = new TemplateEngine();
this.templateEngine.setTemplateResolver(templateResolver);
...
}
}
置 TemplateEngine 对
ServletContextTemplateResolver templateResolver =
new ServletContextTemplateResolver(servletContext);
现Thymeleaf API的
为 org.thymeleaf.templateresolver.ITemplateResolver :
public interface ITemplateResolver {
...
/*
* Templates are resolved by their name (or content) and also (optionally) their
* owner template in case we are trying to resolve a fragment for another template.
* Will return null if template cannot be handled by this template resolver.
*/
public TemplateResolution resolveTemplate(
final IEngineConfiguration configuration,
final String ownerTemplate, final String template,
final Map templateResolutionAttributes);
}
org.thymeleaf.templateresolver.ServletContextTemplateResolver 我
javax.servlet.ServletContext 每
个Java Web应
从Servlet上
从Web应
个GTVG应
templateResolver.setTemplateMode(TemplateMode.HTML);
HTML是
式 ServletContextTemplateResolver ,
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
称“product / list”将
servletContext.getResourceAsStream("/WEB-INF/templates/product/list.html")
配
象
有
很
多
种
⽅
法
,
但
是
现
在
这
⼏
⾏
代
码
将
⾜
以
告
诉
我
们
所
需
的
步
骤
。
模
板
解
析
器
让
我
们
从
模
板
解
析
器
开
始
:
模
板
解
析
器
是
实
接
⼝
的
对
象
,
称
这
些
对
象
负
责
确
定
如
何
访
问
模
板
,
在
这
⽤
程
序
中
,
们
将
下
⽂
中
检
索
模
板
⽂
件
作
为
资
源
的
⽅
式
:
⽤
程
序
中
都
存
在
的
应
⽤
程
序
范
围
的
对
象
,
并
⽤
程
序
根
解
析
资
源
。
但
这
并
不
是
我
们
可
以
说
的
关
于
模
板
解
析
器
的
全
部
内
容
,
因
为
我
们
可
以
在
其
上
设
置
⼀
些
配
置
参
数
。
⼀
,
模
板
模
式
:
默
认
的
模
板
模
但
最
好
还
是
建
⽴
它
,
以
便
我
们
的
代
码
清
楚
地
记
录
正
在
发
⽣
的
事
情
。
该
前
缀
和
后
缀
修
改
,
我
们
将
传
递
到
发
动
机
获
得
要
使
⽤
的
真
实
资
源
名
称
的
模
板
名
称
。
使
⽤
此
配
置
,
模
板
名
对
应
于
:
过cacheTTLMs属
templateResolver.setCacheTTLMs(3600000L);
该TTL之
现 ICacheManager 接
改 StandardCacheManager 对
看Template Engine对
是 org.thymeleaf.ITemplateEngine 接
由Thymeleaf核
org.thymeleaf.TemplateEngine 我
templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
数 TemplateEngine ,
⽤Thymeleaf开
(
可
选
)
通
性
在
模
板
解
析
器
中
配
置
解
析
模
板
可
以
在
缓
存
中
⽣
存
的
时
间
量
:
如
果
达
到
最
⼤
⾼
速
缓
存
⼤
⼩
并
且
它
是
当
前
⾼
速
缓
存
的
最
旧
条
⽬
,
则
在
达
到
前
,
模
板
仍
然
可
以
从
⾼
速
缓
存
中
排
除
。
⽤
⼾
可
以
通
过
实
⼝
或
修
象
来
管
理
默
认
缓
存
来
定
义
缓
存
⾏
为
和
⼤
⼩
。
关
于
模
板
解
析
器
还
有
很
多
东
西
需
要
学
习
,
但
是
现
在
让
我
们
来
看
象
的
创
建
。
模
板
引
擎
模
板
引
擎
对
象
⼝
的
实
现
。
其
中
⼀
个
实
现
是
⼼
提
供
的
:
们
在
这
⾥
创
建
⼀
个
实
例
:
相
当
简
单
,
不
是
吗
?
我
们
所
需
要
的
只
是
创
建
⼀
个
实
例
并
将
模
板
解
析
器
设
置
为
它
。
模
板
解
析
器
是
唯
⼀
需
要
的
参
尽
管
稍
后
将
介
绍
许
多
其
他
参
数
(
消
息
解
析
器
,
缓
存
⼤
⼩
等
)
。
现
在
,
这
就
是
我
们
所
需
要
的
。
我
们
的
模
板
引
擎
现
已
准
备
就
绪
,
我
们
可
以
使
始
创
建
⻚
⾯
。