解析URL地址
代码示例:
<!-- 使用Thymeleaf解析url地址 --> <a th:href="@{/index.html}">访问index.html</a>
经过解析后得到:
/webday08/index.html
所以@{}的作用是在字符串前附加『上下文路径』
这个语法的好处是:实际开发过程中,项目在不同环境部署时,Web应用的名字有可能发生变化。所以上下文路径不能写死。而通过@{}动态获取上下文路径后,不管怎么变都不怕啦!
首页使用URL地址解析
如果我们直接访问index.html本身,那么index.html是不需要通过Servlet,当然也不经过模板引擎,所以index.html上的Thymeleaf的任何表达式都不会被解析。
解决办法:通过Servlet访问index.html,这样就可以让模板引擎渲染页面了:
进一步的好处:
通过上面的例子我们看到,所有和业务功能相关的请求都能够确保它们通过Servlet来处理,这样就方便我们统一对这些请求进行特定规则的限定。
给URL地址后面附加请求参数
3 域对象在Thymeleaf中的使用
回顾域对象
域对象是在服务器中有一定作用域范围的对象,在这个范围内的所有动态资源都能够共享域对象中保存的数据
回顾域对象的类型
1 请求域
在请求转发的场景下,我们可以借助HttpServletRequest对象内部给我们提供的存储空间,帮助我们携带数据,把数据发送给转发的目标资源。
请求域:HttpServletRequest对象内部给我们提供的存储空间
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L7MPhBi2-1645832241874)(/images/img012.png)]
2 会话域
会话域的范围是一次会话(登录与登出为一次会话)
3 应用域(全局域)
应用域的范围是整个项目全局
在Thymeleaf中操作域对象
我们通常的做法是,在Servlet中将数据存储到域对象中,而在使用了Thymeleaf的前端页面中取出域对象中的数据并展示
操作请求域
Servlet中代码:
String requestAttrName = "helloRequestAttr"; String requestAttrValue = "helloRequestAttr-VALUE"; request.setAttribute(requestAttrName, requestAttrValue);
Thymeleaf表达式:
<p th:text="${helloRequestAttr}">request field value</p>
操作会话域
Servlet中代码:
// ①通过request对象获取session对象 HttpSession session = request.getSession(); // ②存入数据 session.setAttribute("helloSessionAttr", "helloSessionAttr-VALUE");
Thymeleaf表达式:
<p th:text="${session.helloSessionAttr}">这里显示会话域数据</p>
操作应用域
Servlet中代码:
// ①通过调用父类的方法获取ServletContext对象 ServletContext servletContext = getServletContext(); // ②存入数据 servletContext.setAttribute("helloAppAttr", "helloAppAttr-VALUE");
Thymeleaf表达式:
<p th:text="${application.helloAppAttr}">这里显示应用域数据</p>
4 获取请求参数
获取请求参数的语法
${param.参数名}
根据一个参数名获取一个参数值
页面代码:
<p th:text="${param.username}">这里替换为请求参数的值</p>
根据一个参数名获取多个参数值
页面代码:
<p th:text="${param.team}">这里替换为请求参数的值</p> 复制代码
如果想要精确获取某一个值,可以使用数组下标。页面代码:
<p th:text="${param.team[0]}">这里替换为请求参数的值</p> <p th:text="${param.team[1]}">这里替换为请求参数的值</p>
OGNL
OGNL的概念
OGNL:Object-Graph Navigation Language对象-图 导航语言
对象图的概念
从根对象触发,通过特定的语法,逐层访问对象的各种属性。
OGNL语法
1 起点
在Thymeleaf环境下,${}中的表达式可以从下列元素开始:
- 访问属性域的起点
- 请求域属性名
- session
- application
- param
- 内置对象
- request
- session
- lists
- strings
2 属性访问语法
- 访问对象属性:使用getXxx()、setXxx()方法定义的属性
- 对象.属性名
- 访问List集合或数组
- 集合或数组[下标]
- 访问Map集合
- Map集合.key
- Map集合[‘key’]
分支与迭代
分支
if和unless
让标记了th:if、th:unless的标签根据条件决定是否显示。
示例的实体类:
package com.atguigu.bean; /** * 包名:com.atguigu.bean * * @author Leevi * 日期2021-05-13 10:58 */ public class Teacher { private String teacherName; public Teacher() { } public Teacher(String teacherName) { this.teacherName = teacherName; } public String getTeacherName() { return teacherName; } public void setTeacherName(String teacherName) { this.teacherName = teacherName; } }
示例的Servlet代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.创建ArrayList对象并填充 List<Employee> employeeList = new ArrayList<>(); employeeList.add(new Employee(1, "tom", 500.00)); employeeList.add(new Employee(2, "jerry", 600.00)); employeeList.add(new Employee(3, "harry", 700.00)); // 2.将集合数据存入请求域 request.setAttribute("employeeList", employeeList); // 3.调用父类方法渲染视图 super.processTemplate("list", request, response); }
示例的HTML代码:
<table> <tr> <th>员工编号</th> <th>员工姓名</th> <th>员工工资</th> </tr> <tr th:if="${#lists.isEmpty(employeeList)}"> <td colspan="3">抱歉!没有查询到你搜索的数据!</td> </tr> <tr th:if="${not #lists.isEmpty(employeeList)}"> <td colspan="3">有数据!</td> </tr> <tr th:unless="${#lists.isEmpty(employeeList)}"> <td colspan="3">有数据!</td> </tr> </table>
if配合not关键词和unless配合原表达式效果是一样的,看自己的喜好。
switch
<h3>测试switch</h3> <div th:switch="${user.memberLevel}"> <p th:case="level-1">银牌会员</p> <p th:case="level-2">金牌会员</p> <p th:case="level-3">白金会员</p> <p th:case="level-4">钻石会员</p> </div>
2.7.2 迭代
<!--遍历显示请求域中的teacherList--> <table border="1" cellspacing="0" width="500"> <tr> <th>编号</th> <th>姓名</th> </tr> <tbody th:if="${#lists.isEmpty(teacherList)}"> <tr> <td colspan="2">教师的集合是空的!!!</td> </tr> </tbody> <!-- 集合不为空,遍历展示数据 --> <tbody th:unless="${#lists.isEmpty(teacherList)}"> <!-- 使用th:each遍历 用法: 1. th:each写在什么标签上? 每次遍历出来一条数据就要添加一个什么标签,那么th:each就写在这个标签上 2. th:each的语法 th:each="遍历出来的数据,数据的状态 : 要遍历的数据" 3. status表示遍历的状态,它包含如下属性: 3.1 index 遍历出来的每一个元素的下标 3.2 count 遍历出来的每一个元素的计数 3.3 size 遍历的集合的长度 3.4 current 遍历出来的当前元素 3.5 even/odd 表示遍历出来的元素是否是奇数或者是否是偶数 3.6 first 表示遍历出来的元素是否是第一个 3.7 last 表示遍历出来的元素是否是最后一个 --> <tr th:each="teacher,status : ${teacherList}"> <td th:text="${status.count}">这里显示编号</td> <td th:text="${teacher.teacherName}">这里显示老师的名字</td> </tr> </tbody> </table>
Thymeleaf包含其他模板文件
创建页面的公共代码片段
使用th:fragment来给这个片段命名:
<div th:fragment="header"> <p>被抽取出来的头部内容</p> </div> 复制代码
在需要的页面中进行包含
语法 | 效果 | 特点 |
th:insert | 把目标的代码片段整个插入到当前标签内部 | 它会保留页面自身的标签 |
th:replace | 用目标的代码替换当前标签 | 它不会保留页面自身的标签 |
th:include | 把目标的代码片段去除最外层标签,然后再插入到当前标签内部 | 它会去掉片段外层标记,同时保留页面自身标记 |
页面代码举例:
<!-- 代码片段所在页面的逻辑视图 :: 代码片段的名称 --> <div id="badBoy" th:insert="segment :: header"> div标签的原始内容 </div> <div id="worseBoy" th:replace="segment :: header"> div标签的原始内容 </div> <div id="worstBoy" th:include="segment :: header"> div标签的原始内容 </div> 复制代码
🌹写在最后💖: 路漫漫其修远兮,吾将上下而求索!伙伴们,再见!🌹🌹🌹