前言
在之前的示例中,我们都是通过@RestController来处理请求,所以返回的内容为json对象。那么如果需要渲染html页面的时候,要如何实现呢?
我们说到了SpringBoot是SSM框架和SSH框架的替代品,那么毫无疑问也是用于搭建Web项目,前面简单了提到了控制层的使用和异常的捕获,这里,我们讲一下前台页面的展示。
SSM框架使用的JSP作为前台展示页面,大家是否知道JSP在运行时将要编译成一个Servlet,这样对服务器是一个大大的消耗。而今天,我们只需要使用前台模版引擎,这种方式就好比静态页面的方式,不需要占用服务器太多的资源,这又是我们转投SpringBoot的有一个不可抗拒的理由。
今天给大家介绍几种前台模版引擎:
Thymeleaf
FreeMarker
Groovy
这里介绍三种,这些都是SpringBoot官方推荐使用的模版,而且特别说出了避免使用JSP,目前用的最多的就是前两种,我这里就用Thymeleaf为大家讲我们的SpringBoot课程。若一定要使用JSP将无法实现Spring Boot的多种特性,后面我们会讲到集成JSP页面。
当我们使用上述模板引擎中的任何一个,SpringBoot默认的模板配置路径为:src/main/resources/templates。当然也可以修改这个路径,具体如何修改,可在后续各模板引擎的配置属性中查询并修改。所以今天我们需要在src/main/resources目录下创建一个templates文件夹用来存放我们的前台模版页面。
当使用模版的时候我们需要在配置文件中添加几条配置,SpringBoot自动会读取默认的配置文件路径是在resources下的application.properties文件,这里我们在配置文件中配置下面的参数
(默认可以不配)
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
所需依赖
我们使用Thymeleaf的话需要引入相关的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- 设置父包,可以版本控制,包含了SpringBoot所需要的所有依赖 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.entor</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- springboot集成web的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 测试类 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- thymeleaf,前端模版框架本质html -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
后端数据
@Controller
public class TestController {
@RequestMapping("index")
public String index(Model model) {
//普通数据
model.addAttribute("title", "用户管理");
model.addAttribute("name","张三");
//对象数据
User user = new User();
user.setId(1);
user.setName("张三");
user.setUsername("zhangsan");
user.setPassword("zhangsan520");
user.setSex(1);
user.setAge(20);
user.setBirthday(new Date());
user.setCreateTime(new Timestamp(new Date().getTime()));
model.addAttribute(user);//隐含的模型对象作为模型数据的存储容器
//Map
HashMap<String, Object> map = new HashMap<>();
map.put("id", 2);
map.put("name", "李四");
model.addAttribute("map", map);
//List
ArrayList<User> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
user = new User();
user.setId(i);
user.setName("张三" + i);
user.setUsername("zhangsan" + i);
user.setPassword("zhangsan520" + i);
user.setSex(i % 2);
user.setAge(20 + i);
user.setBirthday(new Date());
user.setCreateTime(new Timestamp(new Date().getTime()));
model.addAttribute(user);
list.add(user);
}
model.addAttribute("list",list);
return "index";
}
}
前端界面,Thymeleaf的使用
注意:前端的html界面应该写在src/main/resources/templates下
head.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<!--片段表达式 ~{} th:fragment="head定义片段,方便其他文件中导入,增强代码服用性。-->
<head th:fragment="head">
<!--链接表达式:@{}直接拿到应用路径(resource),然后拼到静态资源路径,static目录不需要添加-->
<link type="text/css" rel="stylesheet" th:href="@{/css/style.css}">
<script type="text/javascript" th:src="@{/js/base.js}"></script>
</head>
</html>
index.html
<!DOCTYPE html>
<!--添加th标签属性-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<!--
常用的thymeleaf属性标签:
1、th:text 开闭标签内赋值
2、th:value 标签的value赋值常用input标签
3、th:object 获取数据模型的对象
4、th:each 迭代list
5、th:href 从应用路径(resource)赋值给href
6、th:src 从应用路径赋值给src
8、th:replace 导入视图或着视图片段常与th:fragment一起使用
9、th:inline 从数据模型直接取值给js变量
10、th:if 条件判断成立时为true
11、th:unless 条件判断不成立时为true
-->
<meta charset="UTF-8">
<title th:text="${title}"></title>
<!--
获取head.html文件中的head片段,插入到此处(本次导入为外部css和js)
~{ viewName } 引入整个指定的页面
~{ viewName ::selector} 引入指定页面的片段(th:fragment的值)
~{ ::selector} 在当前页引入指定片段
-->
<script th:replace="head::head"></script>
<!--内联写法,标准格式:[[${xx}]] 可以读取服务端的变量,也可以调用内置对象的方法
添加属性:th:inline="javascript"
-->
<script th:inline="javascript">
var user = [[${user}]];
alert(user.name);
//调用thymeleaf内置对象和方法
var APP_PATH = [[${request.getContextPath()}]]
alert(APP_PATH);
</script>
</head>
<body>
this is my first thymeleaf file
<h3 th:text="Thymeleaf三级标题">三级标题</h3>
<h3>变量表达式</h3>
编号:<input type="text" name="name" th:value="${user.id}"><br/>
姓名:<input type="text" name="name" th:value="${user.name}"><br/>
账户:<input type="text" name="name" th:value="${user.username}"><br/>
密码:<input type="text" name="name" th:value="${user.password}"><br/>
性别:<input type="text" name="name" th:value="${user.sex}"><br/>
年龄:<input type="text" name="name" th:value="${user.age}"><br/>
出生日期:<input type="text" name="name" th:value="${user.birthday}"><br/>
创建日期”<input type="text" name="name" th:value="${user.createTime}"><br/>
<h3>选择变量表达式</h3>
<form th:object="${user}">
编号:<input type="text" name="name" th:value="*{id}"><br/>
姓名:<input type="text" name="name" th:value="*{name}"><br/>
账户:<input type="text" name="name" th:value="*{username}"><br/>
密码:<input type="text" name="name" th:value="*{password}"><br/>
性别:<input type="text" name="name" th:value="*{sex}"><br/>
年龄:<input type="text" name="name" th:value="*{age}"><br/>
出生日期:<input type="text" name="name" th:value="*{birthday}"><br/>
创建日期”<input type="text" name="name" th:value="*{createTime}"><br/>
</form>
<H3>Map: 变量表达式${map.get(key)}或则${map[key]}</H3>
<form>
编号:<input type="text" name="name" th:value="${map.get('id')}"><br/>
姓名:<input type="text" name="name" th:value="${map['name']}"><br/>
</form>
<h3>迭代循环:th:each </h3>
<table border="1">
<tr>
<th>数组下标</th>
<th>当前记录数</th>
<th>总记录数</th>
<th>是否第一条</th>
<th>是否最后一行</th>
<th>是否奇数</th>
<th>是否偶数</th>
<th>id</th>
<th>name</th>
<th>username</th>
<th>password</th>
<th>sex</th>
<th>age</th>
<th>birthday</th>
<th>createTime</th>
<th>操作</th>
</tr>
<tr th:each="user,status:${list}">
<td th:text="${status.index}"></td>
<td th:text="${status.count}"></td>
<td th:text="${status.size}"></td>
<td th:text="${status.first}"></td>
<td th:text="${status.last}"></td>
<td th:text="${status.even}"></td>
<td th:text="${status.odd}"></td>
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.username}"></td>
<td th:text="${user.password}"></td>
<td th:text="${user.sex==1?'男':'女'}"></td>
<td th:text="${user.age}"></td>
<!--日期格式转化:dates.format(user.birthday,'yyyy-MM-dd')-->
<td th:text="${#dates.format(user.birthday,'yyyy-MM-dd')}"></td>
<td th:text="${#dates.format(user.birthday,'yyyy-MM-dd HH:mm:ss')}"></td>
<td>
<a href="">增加</a>
<a href="">删除</a>
</td>
</tr>
</table>
<h3>if条件判断,条件成立时,标签和标签的内容生效,否则失效</h3>
<div th:if="${zhangsan}">
<div><span th:text="${zhangsan}"></span>的确存在..</div>
</div>
<div th:unless="${name}">
<div>不存在..</div>
</div>
</body>
</html>
注意
thymeleaf可以使用${}来获取数据模型内的值(Model、Map),当两个模型的Key一样时,取到的值是最后存放的值。