三、thymeleaf模板引擎
模板引擎介绍及引入
前提说明:我们我们之前在开发web项目的时候使用的是jsp页面来进行前端与后端的数据交互的在,在jsp中支持很多功能,并且可以写java代码。针对于springboot项目首先是以jar包的形式,并不是war包,并且在springboot中我们通过嵌入tomcat的形式来运行项目,所以默认不支持jsp。
若不支持jsp,我们只能使用静态页面了嘛,这样给我们开发带来不便,此时springboot就推荐使用模板引擎。
模板引擎:jsp就是一个模板引擎,还有用的比较多的freemarker,以及包括springboot提供的Thymeleaf,等等。
Thymeleaf官网:https://www.thymeleaf.org/
作用:就是用来写页面模板与jsp类似,后端传来数据,使用一些表达式在页面中展示等
如何使用?我们直接引入依赖即可!在springboot的2.4.1中只需要一个启动器starter
引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>2.4.5</version> </dependency>
实际上thymeleaf也有自动配置类,我们查看以下thymeleafproperties
初体验(测试跳转页面)
首先在templates目录下创建一个test.html页面,页面里包含test提示信息
接着创建一个controller,来进行跳转页面
@Controller public class HelloController { @RequestMapping("/test") public String hello(){ return "test"; } }
这里我们实际上是生成一个modelandview对象,来最终跳转到test.html的!
访问下试试:
thymeleaf如何使用?
介绍及初级使用
导入依赖之后,我们仅需要在对应html页面引入头部声明即可使用
<html lang="en" xmlns:th="http://www.thymeleaf.org"> <!-- 后面xmlns:th部分 -->
对于其中的用法与vue的有很大相似之处,例如vue里面可以绑定标签的属性如使用:v.bind:title v就表示vue
而对于thymeleaf中使用th:开头,例如我要绑定一个元素的text值,就像这样th:text="${}",此时又要问勒后面的${}是什么?
说明:对于html所有的元素都可以被thymeleaf替换接管(例如使用th:text绑定的属性text就被接管了),只有被接管了的才能够使用表达式如${}一类!
我们看个小例子就能够知道了,在/resource/templates/目录下建一个test.html,如下:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div th:text="${msg}"></div> </body> </html>
/java/com…/controller/目录下的HellController如下: @Controller public class HelloController { @RequestMapping("/test") public String hello(Model model) { //设置了model参数实例,将对应键值对存储到request域中 model.addAttribute("msg","长路锅锅!"); return "test";//跳转对应的名称的视图 } }
测试一下:
语法说明
我们这里列举出三个分别时用域输出文本、输出转义字符以及遍历并展示数据:
<!-- 直接就是输出文本--> <div th:text="${msg}"></div> <!-- 可以进行标签转义如<h1> --> <div th:utext="${msg}"></div> <hr> <!--进行遍历list集合--> <h1 th:each="list:${lists}" th:text="${list}"></h1> <!--注意:遍历list集合,输出还有另一种方式直接在标签中输出 不过这种不太常用不推荐--> <h1 th:each="list:${lists}">[[${list}]]</h1>
Controller如下:
@Controller public class HelloController { @RequestMapping("/test") public String hello(Model model) { model.addAttribute("msg","<h1>长路锅锅!</h1>"); model.addAttribute("lists", Arrays.asList("长路学springboot","长路学thymeleaf")); return "test"; } }
效果:
其他一些绑定
简单表达式: 变量表达式:$ {...} 选择变量表达式:\* {...} 消息表达式:#{...} 链接⽹址表达式:@ {...} ⽚段表达式:〜{...} 文字: ⽂字⽂字: 'one text' , 'Another one!' 数字字⾯值:0,34,3.0,12.3,... 布尔⽂字:true,false 空字⾯值:null ⽂字Token:one,sometext,main,... ⽂本操作 字符串连接:+ ⽂本替换:|The name is ${name}| 算术运算符 ⼆进制运算符:+,-,\*,/,% 负号(⼀元运算符):- 布尔运算符 ⼆进制运算符:and 、or 布尔否定(⼀元运算符):!,not ⽐较和相等运算符: ⽐较运算符:>,<,> =,<=(gt,lt,ge,le) 相等运算符:==,!=(eq,ne) 条件运算符: If-then:\(if\) ? \(then\) If-then-else:\(if\) ? \(then\) : \(else\) Default:\(value\) ?: \(defaultvalue\) 特殊符号: 哑操作符:\_
四、SpringMvc自动配置
springmvc自动装配介绍
官方对于springmvc自动配置说明:官方-Spring MVC Auto-configuration
通过官方文档介绍,在默认自动装配过程中包含以下内容:
视图解析器 静态资源,支持webjars 自动注册类型转换器(前台传值,后台自动封装接收)、格式化器2019-12-1转化 http消息转换,用户转换http的请求与响应,比如把user字符串转为json字符串 定义一些错误消息 支持静态首页 头像 支持web数据的初始化绑定,数据请求封装到javabean中
若是我们还想要在保留原有这个功能上再扩展更多的MVC定制如(拦截器、格式化程序、视图控制器以及其他特性)可以添加自己的@Configuration类,其类型应当为webmvcconfiguer。
我们首先看一下webmvcconfiguer究竟是什么?OK,我们可以看到是一个接口
自定义mvc配置类(详细说明)
详细分析
那么我们来进行自定义一个类来接管并扩展mvc,如下:切记不要添加@EnableWebMvc否则mvc直接被全面接管
//结论:如果你想diy一些定制化的功能,只要写这个组件,然后将它交给springboot,springboot就会帮我们自动进行装配 //1、创建一个类并且设置其为配置类 扩展mvc @Configuration public class MyMvcConfig implements WebMvcConfigurer { //3、配置了自己的视图解析器,将MyViewResolver交由spring管理,之后springboot来进行自动装配 @Bean public MyViewResolver myViewResolver(){ return new MyViewResolver(); } //接管视图解析器ContentNegotiatingViewResolver 他实现了ViewResolver接口,那么我们实现这个接口相当于接管了视图解析器 //2、这里我们自定义一个视图解析器,并且重新其中的方法返回空值 public static class MyViewResolver implements ViewResolver { @Override public View resolveViewName(String s, Locale locale) throws Exception { return null; } } }
详细说明:
第1部分
第1部分使用@Configuration不用说了吧,官方介绍若是我们想要自己接管mvc并扩展首先就自己定义一个配置类使用该注解
第2部分
为什么我们要实现ViewResolver来定义一个解析器呢,这里说明一下,主要是想等会体现自己进行自定义视图解析器是否重写了其中的resolveViewName()方法
我们先看官方说明:官方称实现了多个自动配置类,这里我们就使用其来作为讲解
我们看一下ContentNegotiatingViewResolver类,其继承了ViewResolver接口
看一下ViewResolver接口,其实现了一个方法
那么ContentNegotiatingViewResolver类中一定有该接口实现的方法,其方法主要就是选择最佳的视图并进行返回
综上所说,我们第二部分实际上就是实现视图解析的返回view的方法,只不过是我们自定义实现的;
这里为了更好理解我们在干什么,我们回顾一下springmvc中的DispatcherServlet做了什么事吧:
springboot只不过对springmvc进行了自动装配,实际上还是springmvc那一套!!!这里就是为了之后来测试我们自定义mvc配置类是否重写了其中的了视图解析器部分。
参考文章:DispatcherServlet核心方法doDispatch解析)
第三部分
我们既然重写了这个视图解析器的方法,那么我们如何让spring来直接管理这个自定义视图解析的实现类呢?这里我们可以使用需要了解javaconfig,简而言之就是我们通过使用@Bean来让spring对对应方法返回的bean对象进行接管。
(对于@Bean说明,我们通过xml来进行bean的注册,现在我们可以通过javaconfig的方式实现使用注解的方式来注册bean对象。)
建议看这两篇文章:面试官:说说 Springboot 中的 javaConfig(基于Spring5.2) 什么是JavaConfig
综其所说:我们通过@Bean将其自定义的实体类解析器交由spring管理,最终springboot来进行自动配置。
注意:@Bean这个注解就是需要在有@Configuration注解的前提下进行使用的
debug分析
我们上面也讲到了dispatcherservlet,其中自定义mvc配置类也就是重写也原本springmvc实现接口的方法,视图解析器也是在dispatcherservlet执行流程中的一部分,其中的doDispatch()就是执行其中流程的主要方法:
首先将dispatcherServlet类的doDispatch方法打上断点
配合上自定义配置类,我们启动项目,浏览器来访问http://localhost:8080/
接着我们下面Debug窗口中有以下内容,我们能够看到执行了自定义的配置类中的视图解析器
扩展springmvc
重写指定方法来进行视图跳转:
@Configuration public class MyMvcConfig implements WebMvcConfigurer { //进行视图跳转 @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/changlu").setViewName("test"); } }
效果展示:
注意:不要添加@EnableWebMvc注解
首先查看一下这个注解,里面可以看到使用@Import进行了引入了对应类
我们再看一下WebMvcAutoConfiguration这个springboot的自动配置类,能够看到如下的注解,这时候我们就能够明白,一旦我们使用@EnableWebMvc注解引入了对应类,那么springboot再启动时就不会进行该类的自动配置!!!