一、Spring Boot概述
(一)微服务概述
1、微服务
微服务(英语:Microservices)是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关 (Language-Independent/Language agnostic)的API集相互通信;2014年,Martin Fowler 与 James Lewis 共同提出了微服务的概念,定义了微服务是以开发一组小型服务的方式来开发一个独立的应用系统的。其中每个小型服务都运行在自己的进程中,并经常采用HTTP资源API这样轻量的机制来相互通信。这些服务围绕业务功能进行构建,并能通过全自动的部署机制来进行独立部署。这些微服务可以使用不同的语言来编写,并且可以使用不同的数据存储技术。对这些微服务我们仅做最低限度的集中管理。
2、单体应用
(1)单体应用:
一个单块应用系统是以一个单个单元的方式来构建的。企业应用系统经常包含三个主要部分:客户端用户界面、数据库和服务端应用系统,这里的服务端应用系统就是一个单体的应用,系统中任意逻辑发生变化都会导致重新构建部署一个新版本的服务端应用系统。针对单体应用,当访问量变大时,通常采用负载均衡,横向扩展的方式将多个单体应用部署到多个服务器上访问。
(2)单体应用缺点:
软件变更受到了很大的限制,应用系统的一个很小的部分的一处变更,也需要将整个单块应用系统进行重新构建和部署。不能根据用户需求部署应用系统中的功能模块,只能扩展部署整个应用系统。
3、单体应用和微服务对比
4、微服务应用搭建
要搭建一个微服务,运维和部署都变得非常复杂,spring提供了一套解决方案:
springBoot
快速构建单个服务;
springcloud
是一系列有序框架的集合,其主要的设施有,服务发现与注册,配置中心,消息总线,负载均衡,断路器,数据监控等,通过Spring Boot的方式,可以实现一键启动,和部署。
Spring cloud data flow
为基于微服务的分布式流处理和批处理数据通道提供了一系列模型和最佳实践.
(二)Spring Boot简介
Spring-Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。个人理解来说Spring-Boot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,Spring-Boot整合了其他相关联框架。
(三)Spring Boot的优势
1、快速构建项目。
2、对主流开发框架的无配置集成。
3、项目可独立运行,无须外部依赖Servlet容器。
4、提供运行时的应用监控。
5、极大的提高了开发、部署效率。
6、与云计算的天然集成。
(四)Spring Boot的核心功能介绍
1、独立运行Spring项目
Spring Boot 可以以jar包形式独立运行,运行一个Spring Boot项目只需要通过java -jar xx.jar来运行。
2、内嵌servlet容器
Spring Boot可以选择内嵌Tomcat、jetty或者Undertow,这样我们无须以war包形式部署项目。
3、提供starter简化Maven配置
spring提供了一系列的start pom来简化Maven的依赖加载,例如,当你使用了spring-boot-starter-web,会自动加入如图5-1所示的依赖包。
4、自动装配Spring
Spring Boot会根据在类路径中的jar包,类、为jar包里面的类自动配置Bean,这样会极大地减少我们要使用的配置。当然,Spring Boot只考虑大多数的开发场景,并不是所有的场景,若在实际开发中我们需要配置Bean,而Spring Boot没有提供支持,则可以自定义自动配置。
5、准生产的应用监控
Spring Boot提供基于http ssh telnet对运行时的项目进行监控。
6、无代码生产和xml配置
Spring Boot不是借助于代码生成来实现的,而是通过条件注解来实现的,这是Spring4.x提供的新特性。
二、Spring Boot入门程序
(一)创建maven工程导入springboot依赖
Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter 相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器。
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.jn</groupId><artifactId>SpringBootProject01</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.0</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies></project>
(二)编写spring Boot的主程序
1、项目结构
2、主程序代码
@SpringBootApplication: 注解说明这个类是SpringBoot的主配置类,SpringBoot 就应该运行这个类的main方法来启动SpringBoot应用;并将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
package com.jn.springboot;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Example {public static void main(String[] args) {SpringApplication.run(Example.class, args);}
}
(三)编写Controller代码
package com.jn.springboot.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controllerpublic class TestControler {@RequestMapping("/hello")@ResponseBodypublic String hello(){return "hello world";}
}
(四)控制类代码的优化
因为注解@ RestController整合了@Controller和@ResponseBody的注解,所以只要在类注解上面标注@RestController就可以了
package com.jn.springboot.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestControler {@RequestMapping("/hello")public String hello(){return "hello world";}
}
(五)运行主程序进行测试
三、Spring Boot的简化部署
(一)添加maven插件
<!--执行maven命令插件--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>3.2.0</version></plugin></plugins></build>
(二)执行package命令给项目打包
执行打包命令后,会在target目录下生成项目对应的jar包。
(三)执行java -jar命令运行程序
(四)终止进程
Ctl+C终止进程
四、Spring Initializer快速创建Spring Boot项目
(一)创建Spring Boot项目
(二)项目结构解析
1、java文件夹目录结构中自动创建好指定包和Spring Boot启动主程序
SpringbootApplication.class;
2、resources文件夹中目录结构
static:保存所有的静态资源; js css images;
templates:保存所有的模板页面,(Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP页面),可以使用模板引擎(freemarker、thymeleaf);
application.properties:Spring Boot应用的配置文件;可以修改一些默认设置;
五、Spring Boot配置文件
(一)配置文件的作用及规范
Spring Boot使用一个全局的配置文件,配置文件名是固定的;
默认使用以下两种格式:
application.properties
application.yml
配置文件的作用:
修改SpringBoot自动配置的默认值;Spring Boot启动时会根据配置文件自动注册相关的应用组件;
(二)yaml配置文件
1、yaml的语法
YAML:以数据为中心,比json、xml等更适合做配置文件;
(1)基本语法
使用缩进表示层级关系
缩进时不允许使用Tab键,只允许使用空格。
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可 – 大小写敏感
键值对中间必须要有空格k:(空格)v
(2)值的写法
YAML 支持的三种数据结构:
a、字面量:普通的值(数字,字符串,布尔)
server:
port: 8081
注意:字符串默认不用加上单引号或者双引号;
双引号:特殊符号表示转义符本身;
name: "zhangsan \n lisi":输出;zhangsan 换行 lisi
单引号;特殊字符就表示字符本身;
name: ‘zhangsan \n lisi’:输出;zhangsan \n lisi
b、对象、Map(属性和值)(键值对)
person:
name: zhangsan
age: 12
另一种行内写法:
person: {name: zhangsan,age: 12}
c、数组(List,Set)
hobbies:
- singing
- dancing
- running
用-(空格)值表示数组中的一个元素
另一种行内写法:
hobbies: [singing,dancing,running]
2、配置文件值的注入
(1)构建bean对象
Person类对象:
注意:此时省略了Get和Set 以及Tostring方法
@Component
@ConfigurationProperties(prefix = "person")
public class Person {private String name;private int age;private Boolean isMarried;private Date birthDay;private String[] books;private Car car;private Map<String, Object> map;private List<String> list;
}
Car类对象:
private String cname;private Double cvalue;
(2)构建配置文件
person:name: WangYangage: 18birth-day: 2024/11/17isMarried: truebooks: [ "java", "python", "c++" ]car:cname: 宝马cvalue: 11111.0list: [ 1, 2, 3 ]map: { "key1": "value1", "key2": "value2" }
(3)执行单元测试查看person对象的值
package com.jn.springboot;import com.jn.springboot.entity.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class SpringBootProject02ApplicationTests {@Autowiredprivate Person person;@Testvoid contextLoads() {System.out.println(person);}}
(4)测试结果
(三)properties配置文件
1、properties语法
以KEY=VALue键值对的方式设置值
(1)字面量:普通的值(数字,字符串,布尔)
name=张三
(2)对象、Map(属性和值)(键值对)
person.name=张三
person.age=12
maps.key1=value1
maps.key2=value2
(3)数组(List,Set)
hobbies=singing,dancing,running
2、配置文件值的注入
(1)构建配置文件
在构建此配置文件之前,先注释application.yml配置文件,然后再进行配置
person.name="张三"
person.age=18
person.birth-day=1990/01/01
person.is-married=true
person.books=java,python
person.car.cname=ford
person.car.price=100000.00
person.list=1,2,3
person.map.k1=v1
person.map.k2=v2
(2)执行单元测试查看person对象的值
(四)ConfigurationProperties注解和Value注解的区别
1、@ConfigurationProperties注解用于根据配置文件批量注入值,springboot默认配置文件application.yml/application.properties;
2、@Value注解用于根据配置文件单个注入值;
区别 | @ConfigurationProperties | @Value |
SpEL | 不支持 | 支持 |
复杂类型封装 | 支持 | 不支持 |
案例:
@Component
//@ConfigurationProperties(prefix = "person")
public class Person {@Value("${person.name}")private String name;@Value("#{12*2}")private int age;private Boolean isMarried;private Date birthDay;private String[] books;private Car car;private Map<String, Object> map;private List<String> list;}
(五)配置文件中的占位符
1、springboot全局配置文件中可以使用随机数
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}
2、springboot全局配置文件中可以使用占位符
通过${属性名}获取已经在配置文件中加载过的属性值;
通过${属性名:默认值}来指定找不到属性时的默认值;
案例:
person.name=zhangsan
person.age=${random.int:0,100}
person.birth-day=1990/01/01
person.is-married=true
person.books=java,python
person.car.cname=${car.cname:Bwm}
person.car.price=100000.00
person.list=1,2,3
person.map.k1=v1
person.map.k2=v2
(六)多环境支持
Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境;
1、多文件多环境形式:
格式:application-{profile}.properties/yml
例如:可以在项目中创建如下主配置文件:application-dev.properties、application-test.properties、application-prod.properties、application.properties,默认使用application.properties,可以通过配置spring.profiles.active=profile指定使用某个环境的配置文件。
(1) 新建两个properties的配置文件
(2)指定环境配置
(3)测试结果
2、yaml支持单文件多环境形式:
通过---来区分不同的profile环境。
spring:profiles:active: test
---
spring:profiles: dev
server:port: 8081
---
spring:profiles: test
server:port: 8082
(1)出现错误
Property 'spring.profiles' imported from location 'class path resource [application.yml]' is invalid and should be replaced with 'spring.config.activate.on-profile' [origin: class path resource org.springframework.boot.context.config.InvalidConfigDataPropertyException.lambda$throwIfPropertyFound$0(InvalidConfigDataPropertyException.java:113)
(2)解决错误
spring:config:activate:on-profile: test
server:port: 8082
(3)测试结果
(4)发现还是错了
不用管了,以后用不到这样的方法了,查了资料显示SpringBoot的版本已经不支持这样的操作了。
3、激活方式:
在配置文件中指定 spring.profiles.active=dev
命令行 java -jar springboot-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
jvm参数 -Dspring.profiles.active=dev
找不到在哪配置,算了吧。
(七)配置文件加载位置
springboot默认会从以下位置加载配置文件:application.properties/application.yml
项目所在磁盘路径file:./config/
项目所在磁盘路径file:./
项目类路径classpath:/config/
项目类路径classpath:/
优先级由高到底,高优先级的配置会覆盖低优先级的配置;SpringBoot会从这四个位置全部加载主配置文件,互补配置;
如果要加载其他位置的配置文件,可以通过--spring.config.location(只能加到命令行)来指定要加载的配置文件的位置。
六、Spring Boot的web开发
springboot当中静态资源的处理,springboot当中提供的静态资源存放的位置。 在实际当中开发,我们应该满足springboot的约定和规范。如果提供的静态资源目录不能满足实际的需求,还可以自定义静态资源的位置
(一)springboot关于静态资源的处理
springboot启动时会根据配置文件自动配置相应场景的组件xxxAutoConfiguration,web项目启动时会初始化WebMvcAutoConfiguration组件处理请求相关的操作,其中有默认处理静态资源的方法:
1、默认情况下:
(1)匹配/webjars/** 的请求,都去 classpath:/META-INF/resources/webjars/ 找资源;
(2)匹配 "/**" 的请求,都去(静态资源的文件夹)找映射,静态资源文件夹路径如下:
"classpath:/META‐INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"
"/":当前项目的根路径
2、自定义配置静态资源路径:
spring.web.resources.static-locations=自定义路径
1、webjars的使用
我们可以通过webjars以jar包的方式引入静态资源。
(1)引入依赖
<dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.7.0</version>
</dependency>
(2)启动服务访问资源
浏览器访问路径:http://localhost:8080/webjars/jquery/3.7.0/jquery.min.js获取相应的静态资源。
(3)访问结果
2、静态资源的存放位置
(1)默认存放位置查看
默认静态资源路径:
"classpath:/META‐INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"
"/":当前项目的根路径
案例:在上述任意路径下创建静态资源hello.html,浏览器访问路径:http://localhost:8080/hello.html获取相应的静态资源。
a.测试static目录下的静态资源访问
b.测试public目录下的静态资源访问
(2)自定义位置存放
在配置文件中通过属性spring.web.resources.static-locations=自定义路径,设置自定义静态资源存放路径;
案例:新建一个配置文件在resource目录下custom/hallo
a、配置文件中设置
spring.web.resources.static-locations=classpath:/custom/
b、测试
在自定义路径下添加静态资源hello.html,浏览器访问路径:http://localhost:8080/hallo.html获取相应的静态资源。
注意:自定义静态资源路径后,默认静态资源路径失效!
七、springboot web的自动配置
(一)、自动配置原理
1、SpringBootApplication
在Spring Boot项目中有一个注解@SpringBootApplication,这个注解是对三个注解进行了封装:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
其中@EnableAutoConfiguration是实现自动化配置的核心注解。
2、EnableAutoConfiguration
该注解通过@Import注解导入AutoConfigurationImportSelector,这个类实现了一个导入器接口ImportSelector。在该接口中存在一个方法selectImports。
3、selectImports
该方法的返回值是一个数组,数组中存储的就是要被导入到spring容器中的类的全类名。在AutoConfigurationImportSelector类中重写了这个方法。
4、spring.factories
该方法内部就是读取了项目的classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。
5、导入容器
在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。
(二)、初始化自动配置组件
以Spring Boot 自动配置SpringMVC为例,Spring Boot启动时会做以下操作:
1、自动配置视图解析器
自动配置视图解析器ViewResolver(ContentNegotiatingViewResolver 和 BeanNameViewResolver)作用:根据方法返回值得到视图对象,由视图对象决定请求转发或者重定向到指定视图。(注意:此处会创建获取容器中的所有视图解析器,包括自定义的视图解析器)
(1)自定义视图解析器配置
a、创建自己的视图解析器
package com.jn.springbootproject04.viewResolver;import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;import java.util.Locale;public class MyViewResolver implements ViewResolver {@Overridepublic View resolveViewName(String viewName, Locale locale) throws Exception {return null;}
}
b、创建自己的配置类
package com.jn.springbootproject04.configure;import com.jn.springbootproject04.viewResolver.MyViewResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;@Configuration
public class MyConfigure {@Beanpublic ViewResolver myViewResolver(){return new MyViewResolver();}
}
c、断点测试
在此处打上断点启动断点测试,然后浏览器访问localhost:8080
d、测试结果
2、提供静态资源访问路径和webjars访问路径
3、自动注册Converter类型转换器,Formatter格式化器
4、提供HttpMessageConverters
用于Http请求和响应之间的转换,将json或者xml格式字符串和java类型之间做转换;
5、自动注册消息代码提示处理器MessageCodesResolver
6、支持静态首页index.html访问
7、自动注册web数据参数绑定对象ConfigurableWebBindingInitializer
如果我们自己注册了该类型对象,那springboot会自动调用我们注册的对象,替换默认对象将请求参数绑定到javabean(了解)。
8、自定义拦截器
如果要自定义拦截器interceptors,格式化器formatters,视图控制器view controllers等,可以通过创建类型为WebMvcConfigurer的配置类来实现,不要加注解@EnableWebMvc。
i、如果要自定义处理器映射器RequestMappingHandlerMapping, 处理器适配器RequestMappingHandlerAdapter, 或者异常处理器ExceptionHandlerExceptionResolver,可以在容器中创建类型为WebMvcRegistrations的组件对象来实现。
9、小结
a、SpringBoot启动会加载大量的自动配置类
b、根据配置文件和xxxProperties的默认设置初始化自动配置类中的组件
c、可以在自动配置类中查看我们需要的功能是否已经自动配置,如果配置,我们就不用再做配置了;
八、自定义拦截器
(一)登录页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>登录页面</title>
</head>
<body>
<form>Username: <input type="text" name="username"><br>Password: <input type="password" name="password"><input type="submit" value="Submit"></input>
</form>
</body>
</html>
(二)成功跳转页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>登录成功</title>
</head>
<body>
<h2>登录成功</h2>
</body>
</html>
(三)控制类
package com.jn.springbootproject05.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;@Controller
public class LoginController {@RequestMapping("testLogin")public String loginTest(@RequestParam String username, @RequestParam String password){if ("admin".equals(username) && "123456".equals(password)){return "redirect:/success.html";} else {return "redirect:/login.html";}}}
(四)测试
密码不正确,停留在登录页面
密码正确,跳转
跳过登录访问登录成功页面
(五)自定义拦截器
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session = request.getSession();if (session!= null) {String username = (String)session.getAttribute("username");String password = (String)session.getAttribute("password");System.out.println("拦截器处理请求,当前会话ID:" + session.getId());System.out.println("获取到的用户名:" + username);System.out.println("获取到的密码:" + password);System.out.println("会话是否新创建:" + session.isNew());if (username!= null && password!= null) {System.out.println("登录成功不拦截");return true;}}// 直接返回重定向到登录页面response.sendRedirect("/login.html");return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}
(六)修改控制层
@Controller
public class LoginController {@PostMapping("testLogin")public String loginTest(String username,String password, HttpSession session){if ("admin".equals(username) && "123456".equals(password)){session.setAttribute("username",username);session.setAttribute("password",password);return "redirect:/success.html";} else {return "redirect:/login.html";}}}
(七)注册拦截器
@Configuration
public class MyConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/login.html","/testLogin");}
}
(八)测试
现在直接访问 http://localhost:8080/success.html就跳转到了登录界面了
http://localhost:8080/success.html
九、自定义配置视图
(一)添加依赖
<!--模板引擎--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
(二)配置视图控制器
@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/main").setViewName("main");}
(三)main.html页面
在template目录下新建一个main.html的页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h2>main</h2>
</body>
</html>
(四)测试
十、thymeleaf
(一)模板引擎概述
thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎。类似JSP, Velocity,FreeMaker等,它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎。与其它模板引擎相比,Thymeleaf最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用
Spring Boot推荐使用Thymeleaf、Freemarker等后现代的模板引擎技术;一但导入相
关依赖,会自动配置ThymeleafAutoConfiguration、FreeMarkerAutoConfiguration。
模板引擎工作原理图:
(二) SpringBoot使用thymeleaf 入门案例
1 构建maven工程引入技术依赖
<!--thymeleaf-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2 在application.yml当中添加配置
spring:thymeleaf:cache: false #themeleaf 禁用缓存
3 编写Controller文件
@Controller
public class FirstThemleafController {@GetMapping("/hello")public String hello(Model model) {String message = "hello Thymeleaf!";model.addAttribute("message", message);// 返回视图名称,假设success.html在默认的templates目录下return "success";}
}
4 编写模板文件
在resources/templates 下新建 success.html
通过 类似EL 表达式将 Model 中的数据填充到 h2标签中
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
success:
<h2 th:text="${message}"></h2>
</body>
</html>
5 运行访问地址 http://localhost:8080/hello
(三)使用thymeleaf模板进行数据交互
1 Spring boot 集成Thymeleaf打印对象属性
1.1 新建一个实体bean User
省略了get和set方法以及 toString方法
private Integer id;private String name;private String address;
1.2 新建Controller
//集成thymeleaf打印对象属性以及map属性@GetMapping("/user")public String hello2(Model model) {User user = new User(1, "jn", "中国");Map<String, Object> map = new HashMap<>();map.put("src1", "touxiang1.jpg");map.put("src2", "touxiang2.jpg");model.addAttribute("user", user);model.addAttribute("map", map);return "index2";}
1.3 在resource/templates 下,新增模板文件index2.html
<body>
<span th:text="${user.id}"></span>
<span th:text="${user.name}"></span>
<span th:text="${user.address}"></span>
<br>
<img th:src="${map.src1}">
<br>
<img th:src="${map.src2}">
</body>
1.4 访问地址 http://localhost:8080/user
2 Spring boot 集成Thymeleaf循环遍历集合
2.1 新建一个Controller
//集成thymeleaf循环遍历集合@GetMapping("/for")public String hello3(Model model) {List<User> list = new ArrayList<User>();list.add(new User(1001, "令狐冲", "华山"));list.add(new User(1002, "任盈盈", "魔教"));list.add(new User(1003, "岳不群", "华山"));list.add(new User(1004, "东方不败", "魔教"));model.addAttribute("list", list);return "index3";}
2.2 在resource/templates 下,新增模板文件index3.html
<body>
<!--居中显示表格-->
<div align="center"><table width="200" border="1px"><tr><th>学号</th><th>姓名</th><th>地址</th></tr><tr th:each="user,iterStat:${list}"><td th:text="${user.id}"></td><td th:text="${user.name}"></td><td th:text="${user.address}"></td><td th:text="${iterStat.index}"></td></tr></table>
</div>
</body>
iterStat 称作状态变量,属性有:
index:当前迭代对象的 index(从 0 开始计算)
count:当前迭代对象的 index(从 1 开始计算)
size:被迭代对象的大小
current:当前迭代变量
even/odd:布尔值,当前循环是否是偶数/奇数(从 0 开始计算)
first:布尔值,当前循环是否是第一个*
last:布尔值,当前循环是否是最后一个
2.3 访问地址localhost:8080/for
3 Spring boot 集成Thymeleaf赋值、字符串拼接
3.1 新建一个Controller
//集成thymeleaf测试赋值、字符串拼接@GetMapping("/joint")public String hello4(Model model) {model.addAttribute("username", "令狐冲");model.addAttribute("href", "http://www.baidu.com");return "index4";}
3.2 在resource/templates 下,新增模板文件index4.html
<body>
<!--给标签赋值--><h2 th:text="${username}"></h2><br>
<!--给属性赋值--><input type="text" th:value="${username}"><br><em th:size="${username}"></em><br>
<!--字符串拼接--><h2 th:text="'我是'+${username}+'!'"></h2><br>
<!--字符串拼接方式2--><h2 th:text="|好久不见:${username}|"></h2><br>
<a th:href="${href}">百度</a>
</body>
3.3 访问地址: http://localhost:8080/joint
4 Spring boot 集成Thymeleaf条件判断、选择语句
4.1 新建一个Controller
//集成thymeleaf测试条件判断@GetMapping("/ifSwitch")public String hello5(Model model) {model.addAttribute("isAdmin", "true");model.addAttribute("name", "admin");model.addAttribute("manager", "manager");return "index5";}
4.2 在resource/templates 下,新增模板文件index5.html
<body>
<!--th:if 条件成立时显示--><h2 th:if="${isAdmin}=='true'">判断正确,我是Admin</h2>
<!--th:unless 条件不成立时显示--><h2 th:unless="${isAdmin}=='false'">判断错误,我不是Admin</h2>
<!--switch选择语句--><h2 th:switch="${name}"><span th:case="'admin'">I Am Admin</span><span th:case="${manager}">I am a manager</span></h2>
</body>
4.3 访问地址: http://localhost:8080/ifSwitch
5 Spring boot 集成Thymeleaf 静态资源加载
我们知道一个网页中加载的静态文件通常有一个十分尴尬的问题,比如对于bootstrap.css,就是如果我们能让IDE识别这个文件,那么我们得用相对路径来引入这个文件。这样我们的IDE才能加载到这个文件,并且给予我们相应的提示。但是如果我们想要在发布后服务器能够加载这个文件,我们就必须用相对于resources或者static的位置来引入静态文件。显然,一般情况下我们不能兼顾这两个问题,只能要么在编写的时候用相对自己的路径,然后在发布的时候用相对于项目资源文件夹的路径,要么就只能放弃IDE的提示,非常尴尬。
而在Thymeleaf中,我们可很好的处理这一点。在引入资源的时候,我们可以写类似下面的代码:
<link rel="stylesheet" type="text/css" media="all" href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
当我们在没有后台渲染的情况下,浏览器会认得href,但是不认得th:href,这样它就会选择以相对与本文件的相对路径去加载静态文件。而且我们的IDE也能识别这样的加载方式,从而给我们提示。
当我们在有后台渲染的情况下,后台会把这个标签渲染为这样:
<link rel="stylesheet" type="text/css" media="all" href="/css/gtvg.css" />
原来的href标签会被替换成相对于项目的路径,因此服务器就能找到正确的资源,从而正确渲染。非常的智能而且方便。
这里需要注意到所有的路径我们是用”@{}”来引用,而不是”${}”,因为后者是用来引用变量名的,而前者是引用路径的,因此我们在这里用的是前者。可是如果我们是把路径写在变量里,那么就要用后者来引用了
6 Spring boot 集成Thymeleaf 片段fragment定义使用
thymeleaf也提供了类似import的东西,可以将很多代码块抽象成模块,然后在需要的时候引用,非常方便。
fragment(碎片)介绍
fragment类似于JSP的tag,在html中文件中,可以将多个地方出现的元素块用fragment包起来使用。
fragment使用
定义fragment,所有的fragment可以写在一个文件里面,也可以单独存在,例如:
6.1 在resource/templates 下,新增模板文件footer.html
注意: 在Springboot中,默认读取thymeleaf文件的路径是:src/main/resource/templates
<body>
<h1 th:fragment="copy">© 2019-2020 jeff.All Right Reserved.
</h1>
</body>
6.2 编写Controller
//集成thymeleaf测试片段fragment@GetMapping("/fragment")public String hello6(Model model) {return "index6";}
6.3 在resource/templates 下,新增视图文件index6.html
fragment的引用
th:insert:保留自己的主标签,保留th:fragment的主标签。
th:replace:不要自己的主标签,保留th:fragment的主标签。
th:include:保留自己的主标签,不要th:fragment的主标签。(官方3.0后不推荐)
<body>
<!--把片段的内容插入到当前位置--><div style="color: deepskyblue" th:insert="~{footer::copy}"></div>
<!--使用片段的内容替换当前标签--><div style="color: deepskyblue" th:replace="~{footer::copy}"></div>
<!--保留自己的主标签,不要片段的标签--><div style="color: deepskyblue" th:include="~{footer::copy}"></div>
</body>
6.4 访问地址http://localhost:8080/fragment 运行
7 Spring boot 集成Thymeleaf 表达式内置对象使用
7.1 常见内置工具对象如下:
#dates 与java.util.Date对象的方法对应,格式化、日期组件抽取等等
#numbers 格式化数字对象的工具方法
#strings 与java.lang.String对应的工具方法
7.2 编写Controller
//集成thymeleaf测试内置对象@GetMapping("/object")public String hello7(Model model) {//日期格式Date date = new Date();model.addAttribute("date", date);//float格式Double d = 3.1415926;model.addAttribute("float", d);//大文本数据String text = "当你在穿山越岭的另一边\n" +"我在孤独的路上没有尽头\n" +"一辈子有多少的来不及\n" +"发现已经失去\n" +"最重要的东西\n" +"恍然大悟早已远去\n" +"为何总是在犯错之后\n" +"才肯相信错的是自己\n" +"他们说这就是人生\n" +"试着体会试着忍住眼泪\n" +"还是躲不开应该有的情绪\n" +"我不会奢求世界停止转动\n" +"我知道逃避一点都没有用\n" +"只是这段时间里尤其在夜里\n" +"还是会想起难忘的事情\n" +"我想我的思念是一种病\n" +"久久不能痊愈\n" +"当你在穿山越岭的另一边\n" +"我在孤独的路上没有尽头\n" +"时常感觉你在耳后的呼吸\n" +"却未曾感觉你在心口的鼻息\n" +"鼻息";model.addAttribute("text", text);//字符串model.addAttribute("str", "思念是一种病");return "index7";}
7.3 resource/templates 下,新增模板文件index7.html
<body>
Time:<span th:text="${date}"></span><br>
Time:<span th:text="${#dates.format(date,'yyyy-MM-dd HH:mm:ss')}"></span><br>
Price:<span th:text="'¥'+${#numbers.formatDecimal(float,1,2)}"></span><br>
Title:<span th:text="${str}"></span><br>
Message:<span th:text="${#strings.abbreviate(text,60)}"></span><br>
MessageFragment:<span th:text="${#strings.substring(str,0,3)}"></span>
</body>