五、SpringBoot访问静态资源
5.1 静态资源相关目录
SpringBoot项目中没有WebApp目录,只有src目录。在src/main/resources
下面有static
和templates
两个文件夹。SpringBoot默认在static
目录中存放静态资源,而templates
中放动态页面。
static目录
SpringBoot通过/resources/static
目录访问静态资源,在resources/static
中编写html页面:
1、html页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试html</title> </head> <body> <h1>我的HTML</h1> <img src="/img/img.png"> </body> </html>
2、目录结构
templates目录
在SpringBoot中不推荐使用JSP作为动态页面,而是默认使用Thymeleaf编写动态页面。templates目录是存放Thymeleaf页面的目录,稍后。
5.2 静态资源其他存放位置
除了/resources/static
目录,SpringBoot还会扫描以下位置的静态资源:
- /resources/META‐INF/resources/
- /resources/resources/
- /resources/public/
我们还可以在配置文件自定义静态资源位置,例如在resources目录下创建suibian文件:
在SpringBoot配置文件进行自定义静态资源位置配置:
spring: web: resources: static-locations: classpath:/suibian/,classpath:/static/
注意:
- 该配置会覆盖默认静态资源位置,如果还想使用之前的静态资源位置,还需要配置在后面。
- SpringBoot2.5之前的配置方式为:
spring.resources.static-locations
六、Thymeleaf
6.1 Thymeleaf入门
Thymeleaf是一款用于渲染XML/HTML5内容的模板引擎,类似JSP。它可以轻易的与SpringMVC等Web框架进行集成作为Web应用的模板引擎。在SpringBoot中推荐使用Thymeleaf编写动态页面。
Thymeleaf最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用。
Thymeleaf在有网络和无网络的环境下皆可运行,它即可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。没有数据时,Thymeleaf的模板可以静态地运行;当有数据返回到页面时,Thymeleaf标签会动态地替换掉静态内容,使页面动态显示。
1、创建springboot项目,并选择添加的依赖。
2、在template目录编写html页面
<!DOCTYPE html> <!-- 引入thymeleaf命名空间,方便使用thymeleaf属性 --> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>thymeleaf入门</title> </head> <body> <!-- 静态页面显示默认信息,动态页面使用后端传来的msg数据代替 --> <!-- thymeleaf支持el表达式 --> <h2 th:text="${msg}">默认信息</h2> </body> </html>
需要注意的是使用thyme leaf需要在html页面中添加 <html lang="en" xmlns:th="http://www.thymeleaf.org">
thymeleaf语法检查比较严格,有些时候写对了还是爆红,我们只需要将语法检查取消就行了:
3、template中的动态html文件不能直接访问,需要编写Controller跳转到页面中
@Controller public class PageController { // 页面跳转,无返回值时默认跳转到和访问路径相同的页面。 @GetMapping("/index") public void showPage(Model model){ model.addAttribute("msg","Hello Thymeleaf"); } }
4、启动项目,访问http://localhost:8080/index
6.2 变量输出
语法 | 作用 |
th:text | 将model中的值作为内容放入标签中(其实就是request域中的数据,session、application域中的数据都行) |
th:value | 将model中的值放入input 标签的value 属性中 |
1、准备模型数据
// 页面跳转,无返回值时默认跳转到和访问路径相同的页面。 @GetMapping("/index") public void showPage(HttpServletRequest model){ model.setAttribute("msg","Hello Thymeleaf"); }
2、在视图展示model中的值
<h2 th:text="${msg}">默认信息</h2> <input th:value="${msg}">
3、 启动项目,访问http://localhost:8080/index
6.3 操作字符串
Thymeleaf提供了一些内置对象可以操作数据,内置对象可直接在模板中使用,这些对象是以#引用的,操作字符串的内置对象为strings。
方法 | 说明 |
${#strings.isEmpty(key)} | 判断字符串是否为空,如果为空返回true,否则返回false |
${#strings.contains(msg,'T')} | 判断字符串是否包含指定的子串,如果包含返回true,否则返回false |
${#strings.startsWith(msg,'a')} | 判断当前字符串是否以子串开头,如果是返回true,否则返回false |
${#strings.endsWith(msg,'a')} | 判断当前字符串是否以子串结尾,如果是返回true,否则返回false |
${#strings.length(msg)} | 返回字符串的长度 |
${#strings.indexOf(msg,'h')} | 查找子串的位置,并返回该子串的下标,如果没找到则返回-1 |
${#strings.substring(msg,2,5)} | 截取子串,用法与JDK的subString 方法相同 |
${#strings.toUpperCase(msg)} | 字符串转大写 |
${#strings.toLowerCase(msg)} | 字符串转小写 |
1、html
<span th:text="${#strings.isEmpty(msg)}"></span><!--判空--> <br> <span th:text="${#strings.contains(msg,'s')}"></span><!--包含--> <br> <span th:text="${#strings.toUpperCase(msg)}"></span><!--转大写-->
2、控制器
// 页面跳转,无返回值时默认跳转到和访问路径相同的页面。 @GetMapping("/index") public void showPage(HttpServletRequest model){ model.setAttribute("msg","Hello Thymeleaf"); }
3、访问
6.4 操作时间
操作时间的内置对象为dates
方法 | 说明 |
${#dates.format(key)} | 格式化日期,默认的以浏览器默认语言为格式化标准 |
${#dates.format(key,'yyyy/MM/dd')} | 按照自定义的格式做日期转换 |
${#dates.year(key)} | 取年 |
${#dates.month(key)} | 取月 |
${#dates.day(key)} | 取日 |
1、html
<span th:text="${#dates.format(date)}"></span><!--按照浏览器的格式转换时间--> <br> <span th:text="${#dates.format(date,'yyyy-MM-dd')}"></span><!--按照给定格式转换时间--> <br> <span th:text="${#dates.year(date)}"></span><!--获取年--> <br> <span th:text="${#dates.month(date)}"></span><!--获取月份--> <br> <span th:text="${#dates.day(date)}"></span><!--获取天-->
2、控制器
// 页面跳转,无返回值时默认跳转到和访问路径相同的页面。 @GetMapping("/index") public void showPage(Model model){ //Date参数:130表示距离1900后30年也就是2030年 model.addAttribute("date",new Date(130,1,1)); }
3、访问
6.5 条件判断
语法 | 作用 |
th:if | 条件判断 |
1、html
<span th:if="${sex}== '女'"> 性别:女 </span> <span th:if="${sex} == '男'"> 性别:男 </span>
2、控制器
// 页面跳转,无返回值时默认跳转到和访问路径相同的页面。 @GetMapping("/index") public void showPage(Model model){ model.addAttribute("sex","女"); }
3、访问
语法 | 作用 |
th:switch/th:case | th:switch/th:case与Java中的switch语句等效。th:case="*" 表示Java中switch的default,即没有case的值为true时显示th:case="*" 的内容。 |
1、html
<div th:switch="${id}"> <span th:case="1">ID为1</span> <span th:case="2">ID为2</span> <span th:case="3">ID为3</span> <span th:case="*">ID为*</span> </div>
2、控制器
// 页面跳转,无返回值时默认跳转到和访问路径相同的页面。 @GetMapping("/index") public void showPage(Model model){ model.addAttribute("id","12"); }
3、访问
6.6 遍历集合
语法 | 作用 |
th:each | 迭代器,用于循环迭代集合 |
1、pojo
public class User { private String id; private String name; private int age; //get/set/构造略 }
2、控制器
// 页面跳转,无返回值时默认跳转到和访问路径相同的页面。 @GetMapping("/index") public void showPage(Model model){ List<User> users = new ArrayList<>(); users.add(new User("1","谷梦琪",23)); users.add(new User("2","邴梓童",22)); users.add(new User("3","孔新月",25)); model.addAttribute("users",users); }
3、html
<table border="1" width="50%"> <tr> <th>ID</th> <th>Name</th> <th>Age</th> </tr> <!-- 遍历集合的每一项起名为user --> <tr th:each="user : ${users}"> <td th:text="${user.id}"></td> <td th:text="${user.name}"></td> <td th:text="${user.age}"></td> </tr> </table>
4、访问
6.7 遍历时使用状态变量
thymeleaf将遍历的状态变量封装到一个对象中,通过该对象的属性可以获取状态变量:
状态变量 | 含义 |
index | 当前迭代器的索引,从0开始 |
count | 当前迭代对象的计数,从1开始 |
size | 被迭代对象的长度 |
odd/even | 布尔值,当前循环是否是偶数/奇数,从0开始 |
first | 布尔值,当前循环的是否是第一条,如果是返回true,否则返回false |
last | 布尔值,当前循环的是否是最后一条,如果是则返回true,否则返回false |
1、html
<table border="1" > <!--冒号前的第一个对象是遍历出的对象,第二个对象是封装状态变量的对象--> <tr th:each="user,status : ${users}"> <td th:text="${user.id}"></td> <td th:text="${user.name}"></td> <td th:text="${user.age}"></td> <td th:text="${status.index}"></td> <td th:text="${status.count}"></td> <td th:text="${status.size}"></td> <td th:text="${status.odd}"></td> <td th:text="${status.even}"></td> <td th:text="${status.first}"></td> <td th:text="${status.last}"></td> </tr> </table>
2、控制器
// 页面跳转,无返回值时默认跳转到和访问路径相同的页面。 @GetMapping("/index") public void showPage(Model model){ List<User> users = new ArrayList<>(); users.add(new User("1","谷梦琪",23)); users.add(new User("2","邴梓童",22)); users.add(new User("3","孔新月",25)); model.addAttribute("users",users); }
3、访问
6.8 遍历map
1、控制器
// 页面跳转,无返回值时默认跳转到和访问路径相同的页面。 @GetMapping("/index") public void showPage(Model model){ Map<String,User> map = new HashMap<>(); map.put("user1",new User("1","谷梦琪",23)); map.put("user2",new User("2","邴梓童",22)); map.put("user3",new User("3","孔新月",25)); model.addAttribute("map",map); }
2、html
<table border="1" width="50%"> <tr> <th>ID</th> <th>Name</th> <th>Age</th> <th>Key</th> </tr> <!-- 遍历出的是一个键值对对象,key获取键,value获取值 --> <tr th:each="m : ${map}"> <td th:text="${m.value.id}"></td> <td th:text="${m.value.name}"></td> <td th:text="${m.value.age}"></td> <td th:text="${m.key}"></td> </tr> </table>
3、访问
6.9 获取域中的数据
thymeleaf也可以获取request,session,application域中的数据,方法如下:
1、控制器
// 页面跳转,无返回值时默认跳转到和访问路径相同的页面。 @GetMapping("/index") public void showPage(HttpServletRequest request, HttpSession session){ request.setAttribute("req","HttpServletRequest"); session.setAttribute("ses","HttpSession"); session.getServletContext().setAttribute("app","application"); }
2、html
<!--第一种,使用内置对象request获取request对象的方法--> <span th:text="${#request.getAttribute('req')}"></span> <!--第二种,使用httpServletRequest内置对象获取数据--> <span th:text="${#httpServletRequest.getAttribute('req')}"></span> <hr> <!--第一种获取session数据--> <span th:text="${session.ses}"></span> <!--第二种使用内置对象获取数据--> <span th:text="${#httpSession.getAttribute('ses')}"></span> <hr> <!--第一种获取application对象的方法--> <span th:text="${application.app}"></span> <!--第二种使用内置对象获取数据--> <span th:text="${#servletContext.getAttribute('app')}"></span>
3、访问