Spring Boot 整合 Thymeleaf
控制器
@Controller
public class BackstageController {
@RequestMapping("/home")
String home(Model model) {
model.addAttribute("mesg", "hello word!");
return "home";
}
...
引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>thymeleaf 的一些配置
spring.thymeleaf.cache=false//开发环境,禁用缓存
spring.thymeleaf.prefix=classpath:/templates/ //模版路径
spring.thymeleaf.check-template-location=true
spring.thymeleaf.suffix=.html //后缀
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.mode=HTML5建立 thymeleaf 模版文件
在类组建路径建立templates(上配置的)目录, 一般都约定在./resources/templates
在建个home.html文件
内容为:
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
<head>
<meta content="text/html;charset=UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
</head>
<body>
<h1>hi this is home page</h1>
<p th:text="${mesg}">message</p>
</body>
</html>请注意命名空间xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"是必须的
测试
访问: http://127.0.0.1:8080/home
可以看到 <p th:text="${mesg}">message</p> 元素的 message, 被替换为 ${mesg}的值
thymeleaf的常用替换
-
文本替换
<p th:text="${collect.description}">description</p> -
样式替换
th:style="'display:' + @{(${sitrue} ? 'none': 'inline-block')} + ''" -
属性替换
<input th:value="${user.name}" /> -
href
<a th:href="@{/login}" th:unless=${session.user != null}>Login</a> />
其他大多数html都能被替换
foreach
th:each属性用于迭代循环, 语法: th:each=“obj,iterStat:${objList}“
<ol>
<li>List循环:
<table border="1">
<tr>
<th>用户名</th>
<th>邮箱</th>
<th>管理员</th>
<th>状态变量: index</th>
<th>状态变量: count</th>
<th>状态变量: size</th>
<th>状态变量: current.userName</th>
<th>状态变量: even</th>
<th>状态变量: odd</th>
<th>状态变量: first</th>
<th>状态变量: last</th>
</tr>
<tr th:each="user,userStat: ${list}">
<td th:text="${user.userName}">Onions</td>
<td th:text="${user.email}">test@test.com.cn</td>
<td th:text="${user.isAdmin}">yes</td>
<th th:text="${userStat.index}">状态变量: index</th>
<th th:text="${userStat.count}">状态变量: count</th>
<th th:text="${userStat.size}">状态变量: size</th>
<th th:text="${userStat.current.userName}">状态变量: current</th>
<th th:text="${userStat.even}">状态变量: even****</th>
<th th:text="${userStat.odd}">状态变量: odd</th>
<th th:text="${userStat.first}">状态变量: first</th>
<th th:text="${userStat.last}">状态变量: last</th>
</tr>
</table>
</li>
<li>Map循环:
<div th:each="mapS:${map}">
<div th:text="${mapS}"></div>
</div>
</li>
<li>数组循环:
<div th:each="arrayS:${arrays}">
<div th:text="${arrayS}"></div>
</div>
</li>
</ol>
字符串分割迭代
<tbody id="portfolio" class="clear fix">
<tr th:each="brickset: ${bricksets}" th:alt="${brickset.description}">
<td>
<div th:unless="${brickset.imageNames == null}">
<div th:each="image,status: ${#strings.arraySplit(brickset.imageNames, '|')}">
<a href="#" th:href="${imageBaseUrl + image}" th:remove="${image} == null ? tag" th:title="${brickset.brand.name}">
<img src="#" th:src="${imageBaseUrl + image}" height="64" th:remove="${status.index} > 0 ? tag"/>
</a>
</div>
</div>
</td>
</tr>
</tbody>
关于 thymeleaf 的各种使用可以参考: https://www.cnblogs.com/ityouknow/p/5833560.html
静态资源
- 默认静态资源映射规则
Spring Boot 默认将 / 所有访问映射到以下目录:**
classpath:/static
classpath:/public
classpath:/resources
classpath:/META-INF/resources
在application.properties中, 增加如下配置:
# 配置静态资源访问前缀(打包后相对于jar为根目录,放入的文件依然有效, 打包时这个目录无文件是无效的)
spring.mvc.static-path-pattern=/mystatic/**
# 配置静态资源路径 (注意,如果指定了配置, 默认配置将失效)
spring.resources.static-locations[0]=classpath:/mystatic
spring.resources.static-locations[1]=classpath:/public
spring.resources.static-locations[2]=classpath:/static本地路径可以使用file:前缀
spring.resources.static-locations[2]=file:${user.dir}/static
spring.resources.static-locations[2]=file:f:/root/static
注意以上配置也会被
WebMvcConfigurer接口的配置方法addResourceHandlers覆盖!
代码配置
@Configuration
@EnableWebMvc
public class ConfigurerAdapter implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedHeaders("*")
.allowedOrigins("*")
.allowedMethods("GET","POST","PUT","DELETE","OPTIONS");
}
//spring.resources.static-locations=file:${user.dir}/static/, classpath:/static/,classpath:/public/, classpath:/META-INF/resources,classpath:/META-INF/static
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/META-INF/resources/")
.addResourceLocations("classpath:/META-INF/static/")
//
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/public/")
.addResourceLocations("classpath:/resources/")
//本地路径
.addResourceLocations("file:${user.dir}/static/")
.setCachePeriod(0);
}
}获取资源目录
//获取jar内的资源
String PROJECT_ROOT_PATH = ClassUtils.getDefaultClassLoader().getResource("").getPath();
//获取运行jar目录
protected String getResourceDirectory(String directory) {
File path = null;
try {
path = new File(ResourceUtils.getURL("classpath:").getPath());
if(!path.exists() ) path = new File("");
path = new File(path.getAbsolutePath()+"/static/res/"+directory+"/");
if(!path.exists()) path.mkdirs();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return path.getAbsolutePath();
}html模板热更新
另外,修改html模板不自动更新, 还需要引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>再注意
spring.thymeleaf.cache=false,禁用缓存