Thymeleaf 页面静态化模板生成
简介
- 官方网站: https://www.thymeleaf.org/index.html
什么是Thymeleaf ?
- Thymeleaf 官网是这么解释的:
Thymeleaf is a modern server-side Java template engine for both web and standalone environments.
译过来就是:Thymeleaf是适用于Web和独立环境的现代服务器端Java模板引擎
- thymeleaf是一个XML/XHTML/HTML5…模板引擎 可用于Web与非Web环境中的应用开发。
它是一个开源的Java库,基于Apache License 2.0许可Daniel Fernández创建
大佬还是Java加密库Jasypt的作者。
- Thymeleaf允许您处理六种模板,每种模板称为模板模式:
XML,有效的XML,XHTML,有效的XHTML,HTML5 ,旧版HTML5
html 超文本标记语言 xml 可以扩展标记语言这些标签属性就会在DOM(文档对象模型)上执行预先制定好的逻辑。它的特点便是:
开箱即用。
动静分离
- Thymeleaf选用html作为模板页,这是任何一款其他模板引擎做不到的!
- Thymeleaf使用html通过一些特定标签语法代表其含义,但并未破坏html结构, 即使无网络、不通过后端渲染也能在浏览器成功打开,大大方便界面的测试和修改。
-
与JSP 不同它本身就是一个.jsp的文件, 通过服务器数据渲染翻译,成 .html
- 而
Thymeleaf 是通过 html 文件标签中,th:xx 属性进行渲染, 最后还是一个html
静态页面
- 上图的意思就是如果直接打开这个html那么浏览器会
对th等标签忽视而显示原始的内容
- 如果通过服务端访问那么
服务端将先寻找th标签将服务端储存的数据替换到对应位置。
右上角为动态页面通过服务端访问,数据显示为服务端提供的数据,样式依然为html的样式
右下角为静态页面可通过浏览器直接打开,数据为初始的数据
开箱即用
- 它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,
- 避免每天套模板、改标签/jstl,的困扰。同时开发人员也可以扩展和创建自定义的方言。
什么是模板引擎?
- 模板引擎 模板这个意思就是做好一个模板后套入对应位置的数据,最终以特定的格式展示出来,这就是模板引擎的作用。
- 模板引擎是动态网页发展进步的产物,在最初并且流传度最广的 jsp它就是一个模板引擎。
但是由于jsp的缺点比较多也挺严重的,所以很多人弃用jsp选用第三方的模板引擎,
市面上开源的第三方的模板引擎也比较多,有Thymeleaf、FreeMaker、Velocity等模板引擎受众较广。
FreeMaker 常用于xml的模板...
Springboot整合thymeleaf
- 项目基于Springboot框架,且选了Spring web(Springmvc)作为mvc框架
- 其中Thymeleaf就是v(view)视图层
- 我们需要在controller中指定Thymeleaf页面的url,然后再
Model中绑定数据
pom
依赖
pom.xml
<!-- Boot必须父依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencies>
<!-- Boot工程web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- thymeleaf依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
thymeleaf .yml
配置
- 正常情况下也不需要配置什么,强大的Boot 已将集成并默认配置好了很多的属性…
- spring.thymeleaf.cache=false 是否允许页面缓存的配置,默认flase 我们在开发时候要确保页面是最新的所以需要禁用缓存; 而在上线运营时可能页面不常改动为了减少服务端压力以及提升客户端响应速度会允许页面缓存的使用。
- spring.thymeleaf.encoding=UTF-8 来确定页面的编码,但如果你的项目是GBK编码就需要将它改成GBK。
- spring.thymeleaf.prefix=classpath:/templates/ Springboot默认模板引擎文件是放在templates目录下,如果你有需求将模板引擎也可修改配置,将templates改为自己需要的目录。
application.yml
server:
port: 9090
spring:
thymeleaf:
cache: false #开发为了确保数据实时更新,设置 false不缓存
Controller控制层 entity实体
这里直接controller 接受请求输出页面
- 正常MVC 工程,service业务 mapper数据访问层… 目前就直接忽略了。
当然正常的工程是不能忽略的...
user.Java
实体
public class User {
private Integer id;
private String name;
private String address;
//get/set...
}
TestController.Java
//因为是普通的Boot工程,需要返回页面的,就不能使用@RestController 不然就返回页面JSON,而不是页面名了!
@Controller
public class TestController {
//get请求路径
@GetMapping("/test")
public String test(Model model){
//model中封装的数据;
model.addAttribute("name", "wsm");
model.addAttribute("age", 18);
//返回的页面名,并对指定的页面进行 model渲染数据!
return "/test";
}
@GetMapping(value = "/show")
// Model:MVC封装数据的model对象 , @RequestParam 参数给不给都ok!
public String show(Model model, @RequestParam(required = false) Map<String, Object> param) {
//普通数据
model.addAttribute("test", "测试数据!");
//list数据
List<User> users = new ArrayList<>();
users.add(new User(1, "张三1", "徐州"));
users.add(new User(2, "张三2", "徐州"));
users.add(new User(3, "张三3", "徐州"));
users.add(new User(4, "张三4", "徐州"));
//封装对象
model.addAttribute("users", users);
//封装Map数据
Map<String, Object> map = new HashMap<>();
map.put("one", "张三");
map.put("two", "李四");
map.put("thre", "无望");
//存入model
model.addAttribute("map", map);
model.addAttribute("now",new Date()); //时间类型
model.addAttribute("age",20); //数值类型
return "/show"; //默认去:resources/templates/ 目录下找,boot对static目录下也默认放行了...
}
}
静态页面编写
- resources/templates 目录下创建 .html静态页面
默认规格...
- 对于静态资源可以,在resource/static…目录下
resources是Mvc 工程的一般默认存放资源的一个目录!
show.html
<!DOCTYPE html>
<!-- thymeleaf 模板库! -->
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 展示数据 -->
<div th:text="${test}"></div>
<br/>
<!-- 循环数组/list集合....
user 每次循环的对象,用户对象类似数据
status 每次循环的状态对象, .index 可以获取到当前循环下标 0开始;
-->
<div th:each="user,status:${users}">
<span th:text="${status.index}"></span>,
<span th:text="${user.id}"></span>,
<span th:text="${user.name}"></span>,
<span th:text="${user.address}"></span>
</div>
<!-- 遍历map类型数据!map类似 status每次循环的状态 -->
<div th:each="map,status:${map}">
<span th:text="${map}"></span>,
<span th:text="${status.current.key}"></span> <!-- 获取当前元素key -->
<span th:text="${status.current.value}"></span> <!-- 获取当前元素value,当然value可能还是一个mao/JSON复杂类型可以继续进行遍历...-->
</div>
<!-- 时间:设置时间显示格式! -->
<div th:text="${#dates.format(now,'yyyy-MM-dd HH:mm:ss')}"></div>
<!-- 判断 -->
<div th:if="${age<18}">
未成年人
</div>
<div th:if="${age>=18}">
成年人
</div>
<!-- 取反判断 -->
<div th:unless="${age<18}">
unless---未成年人
</div>
</body>
</html>
测试:
thymeleaf常用语法:
标签 | 作用 | 示例 |
---|---|---|
th:id | 替换id | <input th:id="${user.id}"/> |
th:text | 文本替换 | <p text:="${user.name}">bigsai</p> |
th:utext | 持html的文本替换 | <p utext:="${htmlcontent}">content</p> |
th:object | 替换对象 | <div th:object="${user}"></div> |
th:value | 替换值 | <input th:value="${user.name}" > |
th:each | 迭代 | <tr th:each="student:${user}" > |
th:href | 替换超链接 | <a th:href="@{index.html}">超链接</a> |
th:src | 替换资源 | <script type="text/javascript" th:src="@{index.js}"></script> |
域对象
代码语言:javascript复制 <!-- 域对象取值方式 -->
Request:<span th:text="${#httpServletRequest.getAttribute('req')}"></span>|
Session:<span th:text="${session.se}"></span>|
Application:<span th:text="${application.app}"></span><hr/>
- 基本语法其实也与 html 基本无异,属性前面加一个 th: 基本如此…
需要时候学习一下即可!
常用场景:
比如拼接url 与上面demo没关系
th:src th:href…
- 例如京东商城:
根据选择,动态拼接需要的条件参数...
截取url参数拼接:
//根据页面参数拼接对应url
public String myurl(Map<String, String> searchMap) {
//固定搜索请求
String url = "/search";
//循环分享每个参数对象,进行拼接成为一个新的 url
if (searchMap != null && searchMap.size() > 0) {
url = "?";
for (Map.Entry<String, String> entry : searchMap.entrySet()) {
if (entry.getKey().equals("rule") || entry.getKey().equals("feild")) {
continue;
}
url = entry.getKey() "=" entry.getValue() "&";
}
//截取最后一个 & 字符!
url = url.substring(0, url.length() - 1);
}
return url;
}
- 这里并没有进行一些特殊字符的拼接, 如果页面参数存在 - * / 特殊字符… 这里是需要进行转义拼接的;
需要注意
模板——动态生成多个静态页面!
- Thymeleaf 是一个模板技术,最强之处在于 可以根据一个模板生成,多个静态资源! 正常的简历模板都是 姓名 年龄 工作经验…格式大致相同只是内容不一样罢了~ 这就是模板!
- Boot 整合 Thymeleaf 动态生成静态模板! 还是上面Demo进行更改!
依赖
配置 .yml
添加一个配置,其实不要也ok 的
server:
port: 9090
spring:
thymeleaf:
cache: false
# 设置动态生成静态资源存放的位置!
pagepath: C:Users王斯明Desktop微服学习23 Thymeleaf 页面静态化模板生成springboot.thymleafsrcmainresourcesll
Thymeleaf静态模板页面
test.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" > <!-- Thymeleaf的模板库 -->
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:text="${item}" >itme数据!</h1>
</body>
</html>
Service 业务逻辑代码 关键
TestService.Java
@Service
public class TestService {
@Autowired
private TemplateEngine templateEngine; //template模板对象
@Value("${pagepath}")
private String pagepath; //pagepath yml中的静态资源存放路径
public Map<String,Object> item(Integer id,String name){
Map<String,Object> map = new HashMap<>();
map.put("item", "我叫" name "id:" id);
return map;
}
//创建静态页面
public void createHtml(Integer id,String name) throws Exception {
//数据对象
Context context = new Context();
context.setVariables(item(id,name)); //调用方法!
//获取一个文件目录对象
File file = new File(pagepath);
//判断文件是否存在,不存在创建
if (!file.exists()) {
file.mkdir();
}
//创建一个 id.html文件,设置编码utf-8
File htmlFile = new File(file, id ".html");
PrintWriter printWriter = new PrintWriter(htmlFile, "UTF-8");
//指定生成: 模板 数据 编码格式
templateEngine.process("item", context, printWriter);
}
}
主程序调用:
Test.Java
@SpringBootApplication
public class Test {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext run = SpringApplication.run(Test.class, args);
//获取Spring容器中对象
TestService ts = run.getBean(TestService.class);
ts.createHtml(123, "wsm");
}
}
运行测试:
控制台并没有什么信息,但是可以看到 ll目录下出现了一个静态资源页面!
- 这就是动态生成的模板!启动服务请求页面发现并请求不了…
因为Boot对于静态资源进行拦截了,需要进行放行
Boot 静态资源放行:
Config包下配置类:
EnableMvcConfig.Java
@ControllerAdvice
@Configuration
public class EnableMvcConfig implements WebMvcConfigurer { //SpringBoot 放行静态资源! 允许加载
/***
* 静态资源放行
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//addResourceHandler是指你想在url请求的路径 格式: 前缀/** (这里aaa可随意更换或不填,页面访问时候根据这里来!)
//addResourceLocations是图片存放的真实路: classpath 可更换为 file 设置绝对路径下静态资源!
registry.addResourceHandler("aaa/**").addResourceLocations("classpath:/ll/");
}
}
总结:
- Thymeleaf 并不难!归根结底就是一个 , 类似于JSP 的一个模板技术,已.html文件为模板进行动态生成绑定数据的一个技术!
- 实际开发中,对于 用户访问量高,项目 浏览器对于
静态页面
加载快,且更加兼容 采用 静态页面比较ok! - 当然实际开发中,数据可能来源于多个模块!且更加复杂…这个是需要注意的!
- 为了确保不存在
脏数据
使用 Canal 进行动态的数据更新 重新生成一个静态页面即可!相同名字的文件默认进行覆盖!