在Spring boot中,官方默认采用的是Thymeleaf模块引擎,通过org.springframework.boot.autoconfigure.thymeleaf包对Thymeleaf进行了自动配置。

通过Thymeleaf2Configuration类对集成所需要的Bean进行自动配置,包括templateResolver、templateViewResolver 和templateEngine 的配置。
通过ThymeleafProperties来配置Thymeleaf,在application.properties中以 spring.thymeleaf开头来配置,通过查看ThymeleafProperties的主要源码,可以看出如何设置属性及默认配置:
/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.thymeleaf;
import java.nio.charset.Charset;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.MimeType;
/**
* Properties for Thymeleaf.
*
* @author Stephane Nicoll
* @since 1.2.0
*/
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");
private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
/**
* 在渲染之前检查模板是否存在(Thymeleaf 3+)。
*/
private boolean checkTemplate = true;
/**
* 检查模板位置是否存在。
*/
private boolean checkTemplateLocation = true;
/**
* Spring boot 默认模板路径,默认在classpath:/templates/目录下
*/
private String prefix = DEFAULT_PREFIX;
/**
* 后缀设置,默认为html.
*/
private String suffix = DEFAULT_SUFFIX;
/**
* 模板模式设置,默认为html5
*/
private String mode = "HTML5";
/**
* 模板的编码设置,默认UTF-8
*/
private Charset encoding = DEFAULT_ENCODING;
/**
* 模板的媒体类型设置,默认为text/html
*/
private MimeType contentType = DEFAULT_CONTENT_TYPE;
/**
* 是否开启模板缓存,默认是开启的,开发时建议关闭
*/
private boolean cache = true;
/**
* Order of the template resolver in the chain. By default, the template resolver is
* first in the chain. Order start at 1 and should only be set if you have defined
* additional "TemplateResolver" beans.
*/
private Integer templateResolverOrder;
/**
* Comma-separated list of view names that can be resolved.
*/
private String[] viewNames;
/**
* Comma-separated list of view names that should be excluded from resolution.
*/
private String[] excludedViewNames;
/**
* Enable MVC Thymeleaf view resolution.
*/
private boolean enabled = true;
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isCheckTemplate() {
return this.checkTemplate;
}
public void setCheckTemplate(boolean checkTemplate) {
this.checkTemplate = checkTemplate;
}
public boolean isCheckTemplateLocation() {
return this.checkTemplateLocation;
}
public void setCheckTemplateLocation(boolean checkTemplateLocation) {
this.checkTemplateLocation = checkTemplateLocation;
}
public String getPrefix() {
return this.prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return this.suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public String getMode() {
return this.mode;
}
public void setMode(String mode) {
this.mode = mode;
}
public Charset getEncoding() {
return this.encoding;
}
public void setEncoding(Charset encoding) {
this.encoding = encoding;
}
public MimeType getContentType() {
return this.contentType;
}
public void setContentType(MimeType contentType) {
this.contentType = contentType;
}
public boolean isCache() {
return this.cache;
}
public void setCache(boolean cache) {
this.cache = cache;
}
public Integer getTemplateResolverOrder() {
return this.templateResolverOrder;
}
public void setTemplateResolverOrder(Integer templateResolverOrder) {
this.templateResolverOrder = templateResolverOrder;
}
public String[] getExcludedViewNames() {
return this.excludedViewNames;
}
public void setExcludedViewNames(String[] excludedViewNames) {
this.excludedViewNames = excludedViewNames;
}
public String[] getViewNames() {
return this.viewNames;
}
public void setViewNames(String[] viewNames) {
this.viewNames = viewNames;
}
}
以上关于ThymeleafProperties类的中文注释,为个人根据代码理解及其原代码英文注释而来。
在spring boot中整合Thymeleaf需要加入对Thymeleaf的依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
创建一个HelloController 类,通过spring mvc 返回页面,来通过Thymeleaf渲染一个页面。
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping(value = "/hello")
public String hello(ModelMap map){
// 加入一个属性,用来在模板中读取
map.addAttribute("host", "http://www.baikeyang.com");
// return模板文件的名称,对应src/main/resources/templates/index.html
return "index";
}
}<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
<meta charset="UTF-8" >
<title></title>
</head>
<body>
<h1 th:text="${host}">Hello World</h1>
<br/>
</body>
</html>直接打开html页面展现Hello World,但是启动程序后,访问http://localhost:8080/hello,则是展示Controller中host的值:http://www.baikeyang.com,做到了不破坏HTML自身内容的数据逻辑分离。
#Thymeleaf配置 #Thymeleaf模板模式 spring.thymeleaf.mode = HTML5 #Thymeleaf 编码 spring.thymeleaf.encoding = UTF-8 #模板缓存(热部署静态文件) spring.thymeleaf.cache = false #spring.thymeleaf.prefix=classpath:/templates/:指定Thymeleaf的页面文件放置的位置(也就是页面文件的前缀),这里的classpath:/templates/指的目录就是src/resources/templates,所以需要创建templates这个目录(默认是没有这个目录的) spring.thymeleaf.prefix = classpath:/templates/ #检查模板位置是否存在 spring.thymeleaf.check-template-location = true #指定页面文件的后缀,这里配置所有页面文件都是.html的文件 spring.thymeleaf.suffix = .html #内容类型 spring.thymeleaf.content-type = text/html
启动项目,直接访问,会有一个异常抛出:
org.xml.sax.SAXParseException: 元素类型 "meta" 必须由匹配的结束标记 "</meta>" 终止。
spring.thymeleaf.mode的默认值是HTML5,其实是一个很严格的检查,对.html的内容要求很严格,比如<meta charset="UTF-8" />,如果少最后的标签封闭符号/,就会报错而转到错误页。也比如你在使用<br/>、<link>、<meta>这样的html标签,也会被thymeleaf认为不符合要求而抛出错误。
因为,我可以调整spring.thymeleaf.mode,改为LEGACYHTML5可以得到一个可能更友好亲切的格式要求。
需要注意的是,LEGACYHTML5需要搭配一个额外的库NekoHTML才可用。需要给项目添加NekoHTML的依赖:
<dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.22</version> </dependency>
最后重启项目就可以感受到不那么严格的thymeleaf了,访问正常。
评论