前言
服务器渲染
除了我们熟悉的JSP,还有Velocity, Freemarker,Thymeleaf等视图模板技术.虽然具体雨大各不相同 , 但是他们都有一个共同点 , 就是在固定内容中可以穿插格子表达式形式的动态内容 , 将视图模板的动态内容转换为对应的java代码并执行 , 然后使用计算得到的具体数据替换原来的动态部分. 这样整个文件的动态内容就可以作为确定的响应结果返回给浏览器. 在这种模式下 ,前端工程师将前端页面全部开发完成, 交给后端程序员加入到项目中, 此时不可避免的需要后端程序员根据需要对前端代码进行补充和调整.
前后端分离
前后端分离模式下,前端程序员和后端程序员使用JSON格式进行交互,所以数启动时前端工程师和后端工程师需要坐到一起开会,商量确定JSON格式的具体细节. 然后分头开发. 后端工程师在把后端代码发布到测试服务器之前,前端工程师都无法调用后端程序拿到真实数据 , 所以使用MOck.js生成假数据. 知道后端工程师开发完成, 后端程序发布到了测试服务器上,前端工程师再从Mock.js切换到实际代码
Thymeleaf使用
环境搭建
1.新建一个springboot项目,加入以下依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.0</version>
<scope>compile</scope>
</dependency>
2.在根路径下新建一个thymeleaf文件夹存放html页面
这个路径是可以通过yml更改的, 具体看ThymeleafProperties类中的属性
3.在这个文件夹中创建一个html文件 , 加入以下内容
<!DOCTYPE html>
<!-- 加入thymeleaf名称空间 -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 服务器解析thymeleaf代码时, 会读取th:test属性的值, 用这个值替换原本标签体的值 -->
<p th:text="经过服务器处理可以看到的内容">你他吗好啊!</p>
</body>
</html>
然后再浏览器直接打开
启动springboot后打开
看到这里你应该可以理解为什么Thymeleaf对前端工程师友好了吧?
修改标签文本
如上面代码所示
<p th:text="经过服务器处理可以看到的内容">你他吗好啊!</p>
修改指定属性值
在属性前加 th: 即可修改
<h3>替换属性值</h3>
<input type="text" value="旧的值" th:value="用thy去替换旧的值"/>
效果:
在表达式中访问属性域
后端加入测试数据
@RequestMapping("/Thymeleaf/page.html")
public String testThy(ModelMap model, HttpSession session){
model.addAttribute("modeltestmsg","开冲了兄弟萌");
session.setAttribute("sessiontestmsg","收到!");
return "hello";
}
页面上加入
<h3>访问属性域</h3>
<p th:text="${modeltestmsg}">访问属性域</p>
效果:
也可以这样写 , 效果是一样的 ,只是这种更加明确的说明是从请求域拿到的数据
<h3>访问属性域(方法2)</h3>
<p th:text="${#httpServletRequest.getAttribute('modeltestmsg')}">访问属性域</p>
顺带一提 , 访问session域也是大同小异 , 括号里面切记要写单引号,以免字符串被解析成变量
<h3>访问session域</h3>
<p th:text="${#session.getAttribute('sessiontestmsg')}">访问属性域</p>
解析URl地址
因为springboot默认的contextPath的值是空 , 所以我们先去yml文件给它设置一个
server:
servlet:
context-path: /lja
然后在页面上加入如下代码
<h3>获取contextPath的值</h3>
<p th:text="@{/aa/vv/bb}">@{}的作用是吧contextPath的值附加到指定的地址前面</p>
效果
执行表达式
通常分为转义和非转义两种, 通常很少用到
<h3>执行表达式</h3>
<h3>有转义效果</h3>
<p>[[${htmlcode}]]</p>
<h3>无转义效果</h3>
<p>[(${htmlcode})]</p>
后端
@RequestMapping("/Thymeleaf/page.html")
public String testThy(ModelMap model, HttpSession session){
model.addAttribute("htmlcode","<p style='color:red;font-size:30px;'>这里是后端传入的html代码</p>");
return "hello";
}
效果:
区别在于是否有识别html代码吧, 大概
判断
<h3>if判断</h3>
<p th:if="${not #strings.isEmpty(modeltestmsg)}">modeltestmsg不为空</p>
-<p th:if="${ #strings.isEmpty(modeltestmsg)}">modeltestmsg不为空</p>-
<!-- 因为不为空所以返回true -->
效果:
循环
@RequestMapping("/Thymeleaf/page.html")
public String testThy(ModelMap model){
List list = new ArrayList();
list.add("apple");
list.add("bannane");
list.add("watermalon");
model.addAttribute("fruits",list);
return "hello";
}
<!-- 遍历从请求域传过来的值 -->
<h3>each循环</h3>
<p th:text="${fruit}" th:each="fruit : ${fruits}"></p>
效果:显示了请求域中fruits集合中的所有值
包含其他页面
创建一个html页面 , 叫part
<div th:fragment="myFirstPart">
<p>include myFirstPart</p>
</div>
<div th:fragment="mySecondPart">
<p>include mySecondPart</p>
</div>
<div th:fragment="myThirdPart">
<p>include myThirdPart</p>
</div>
主页面加上
<h3>包含页面片段</h3>
<!--双冒号::左边的值拼前后缀必须能够找到要包含的文件-->
<!-- 右边的值是代码片段的名字-->
<div th:insert="~{include/part :: myFirstPart}"></div>
<div th:insert="~{include/part :: mySecondPart}"></div>
<div th:insert="~{include/part :: myThirdPart}"></div>
效果:
未完待续!