SpringBoot学习笔记(一)

一、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">&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>
7.4 运行访问地址 http://localhost:8080/object

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/475616.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++初阶(十三)--STL--vector的使用

目录 ​编辑 一、vector的基本介绍 二、vector的使用 1.构造函数的介绍 2.容量操作 size和capacity reserve和resize empty 3.vector的遍历 operator[ ](size_t n) 迭代器使用 begin和end rbegin和rend 4.vector的增删查改 push_back和pop_back insert和erase fi…

用Python爬虫“偷窥”1688商品详情:一场数据的奇妙冒险

引言&#xff1a;数据的宝藏 在这个信息爆炸的时代&#xff0c;数据就像是一座座等待挖掘的宝藏。而对于我们这些电商界的探险家来说&#xff0c;1688上的商品详情就是那些闪闪发光的金子。今天&#xff0c;我们将化身为数据的海盗&#xff0c;用Python这把锋利的剑&#xff0…

matlab的函数名和函数文件名的关系(编程注意事项)

在MATLAB中&#xff0c;函数名和函数文件名之间有着重要的关系。以下是它们之间的关系以及在编程时需要注意的事项 文章目录 函数名与函数文件名的关系编程时的注意事项结论 函数名与函数文件名的关系 一致性要求&#xff1a; 在MATLAB中&#xff0c;函数文件的文件名必须与函数…

【Redis】持久化机制RDB与AOF

一、RDB RDB模式是就是将内存中的数据存储到磁盘中&#xff0c;等到连接断开的时候会进行持久化操作。但是如果服务器宕机&#xff0c;会导致这个持久化机制不会执行&#xff0c;但是内存中的文件会直接丢失。所以可以设置一个触发机制&#xff0c;save 60 1000 就是代表60秒 执…

基于Lora通讯加STM32空气质量检测WIFI通讯-分享

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着环境污染问题的日益严重&#xff0c;空气质量的监测与管理已经…

【MySQL】ubantu 系统 MySQL的安装与免密码登录的配置

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;MySQL初阶探索&#xff1a;构建数据库基础 欢迎大家点赞收藏评论&#x1f60a; 目录 &#x1f4da;mysql的安装&#x1f4d5;MySQL的登录&#x1f30f;MySQL配置免密码登录 &#x1f4da;mysql的…

【STK学习】part2-星座-目标可见性与覆盖性分析

【Satellite Tool Kit】学习并深入了解卫星/星座生成、可见性分析、覆盖性分析等知识&#xff0c;并基于STK软件实现对应数据的导出&#xff0c;以用于算法的约束输入。 文章目录 一、学习目标二、学习内容2.1 星地可见性分析2.1.1 单星单地2.1.2 单星多地2.1.3 多星单地 2.2 星…

框架实战:SSM整合原理和实战

1. SSM整合理解 1.1. IOC两个容器对应组件 容器名盛放组件web容器web相关组件&#xff08;controller,springmvc核心组件&#xff09;root容器业务和持久层相关组件&#xff08;service,aop,tx,dataSource,mybatis,mapper等&#xff09; 配置文件 配置名对应内容对应容器Web…

自然语言处理:第六十三章 阿里Qwen2 2.5系列

本人项目地址大全&#xff1a;Victor94-king/NLP__ManVictor: CSDN of ManVictor 项目地址: QwenLM/Qwen2.5: Qwen2.5 is the large language model series developed by Qwen team, Alibaba Cloud. 官网地址: 你好&#xff0c;Qwen2 | Qwen & Qwen2.5: 基础模型大派对&a…

i春秋-登陆(sql盲注爆字段,.git缓存利用)

练习平台地址 竞赛中心 题目描述 先登陆再说 题目内容 就是一个登录框 测试登录 用户名&#xff1a;admin or 11# 密码&#xff1a;随便输 返回密码错误 用户名&#xff1a;随便输 密码&#xff1a;随便输 返回用户名不存在 这里就可以确定时一个bool盲注了 这里提供一个lik…

新华三H3CNE网络工程师认证—子接口技术

子接口&#xff08;subinterface&#xff09;是通过协议和技术将一个物理接口&#xff08;interface&#xff09;虚拟出来的多个逻辑接口。在VLAN虚拟局域网中&#xff0c;通常是一个物理接口对应一个 VLAN。在多个 VLAN 的网络上&#xff0c;无法使用单台路由器的一个物理接口…

C# - 无法加载 DLL“libmupdf.dll”: 找不到指定的模块。

1.本机环境 windows 11 64位Visual Studio 2015 2.报错如下 用户代码未处理 System.DllNotFoundException HResult-2146233052 Message无法加载 DLL“libmupdf.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。 SourceMoonPdfLib TypeName"" StackTrac…

23.UE5删除存档

2-25 删除存档制作_哔哩哔哩_bilibili 按照自己的风格制作删除按钮 这样该行的存档就被从存档列表中删除了&#xff0c;并且实际存档&#xff08;我的存档蓝图&#xff09;中也被删除了 但是存在一个问题&#xff0c;如果存档数据中存在索引为: 0 1 2 3的存档&#xff0c;当索…

VSCode DeBug时无法进入自定义工具库

最近遇到一个问题&#xff0c;将自己的写的工具包放到conda里site-packagse下&#xff0c;并配置了__init__.py文件&#xff0c;当我debug时&#xff0c;想进入工具包函数调试&#xff0c;但是总是进入不了工具包函数。找了许多博客方法&#xff0c;尝试了将launch.json中的jus…

单元测试框架gtest学习(三)—— 事件机制

前言 上节我们学习了gtest的各种宏断言 单元测试框架gtest学习&#xff08;二&#xff09;—— 认识断言-CSDN博客 本节我们介绍gtets的事件机制 虽然 Google Test 的核心是用来编写单元测试和断言的&#xff0c;但它也允许在测试执行过程中进行事件的钩取和自定义&#xf…

在k8s上部署Crunchy Postgres for Kubernetes

目录 一、前言二、安装Crunchy Postgres for Kubernetes三、部署一个简单的postgres集群四、增加pgbouncer五、数据备份六、备份恢复七、postgres配置参数八、数据导入九、权限管理 一、前言 Crunchy Postgres可以帮助我们在k8s上快速部署一个高可用、具有自动备份和恢复功能的…

python中Pandas操作excel补全内容

补全ID、InStore、Date import random from datetime import datetime, timedeltaimport pandas as pdfile_path r"C:\Users\xb\Desktop\Books_1.xlsx" books pd.read_excel(iofile_path, skiprows3, usecols"C:F", dtype{"ID": str, "I…

高级 SQL 技巧讲解

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; SQL&#xff08;结构化查询语言&#xff09;是管理和操作数据库的核心工具。从基本的查询语句到复杂的数据处理&#xff0c;掌握高级 SQL 技巧不仅能显著提高数据分析的效率&#xff0c;还能解决业务中的复…

Android okhttp 网络链接各阶段监控

步骤 1: 添加依赖 在项目的 build.gradle 文件中&#xff0c;添加 OkHttp 依赖&#xff1a; implementation com.squareup.okhttp3:okhttp:4.11.0 步骤 2: 创建自定义的 EventListener 创建一个自定义的 EventListener 类&#xff1a; import android.util.Log import okht…

springboot高校毕业生实习及就业去向信息管理系统

摘 要 高校毕业生实习及就业去向信息管理管理系统采用B/S架构&#xff0c;数据库是MySQL。网站的搭建与开发采用了先进的java进行编写&#xff0c;使用了springboot框架。该系统从三个对象&#xff1a;由管理员和学生、企业信息来对系统进行设计构建。主要功能包括&#xff1a…