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.xdnf.cn/news/20529.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

SD模型微调之LoRA

​ &#x1f33a;系列文章推荐&#x1f33a; 扩散模型系列文章正在持续的更新&#xff0c;更新节奏如下&#xff0c;先更新SD模型讲解&#xff0c;再更新相关的微调方法文章&#xff0c;敬请期待&#xff01;&#xff01;&#xff01;&#xff08;本文及其之前的文章均已更新&a…

手机远程控制电脑,让办公更快捷

在数字化办公的浪潮下&#xff0c;远程控制软件已成为连接工作与生活的桥梁。它使得用户能够通过一台设备&#xff08;主控端&#xff09;来操作另一台设备&#xff08;被控端&#xff09;&#xff0c;无论它们是否位于同一局域网内。这种软件广泛应用于远程办公、手机远程控制…

【Three.js基础学习】26. Animated galaxy

前言 shaders实现星系 课程回顾 使用顶点着色器为每个粒子设置动画 a属性 &#xff0c; u制服 &#xff0c;v变化 像素比&#xff1a;window.devicePixelRatio 自动从渲染器检索像素比 renderer.getPixelRatio() 如何尺寸衰减&#xff0c; 放大缩小视角时&#xff0c;粒子都是同…

基于Springboot + Vue的旧物置换网站管理系统(源码+lw+部署讲解+PPT)

前言 详细视频演示 论文参考 系统介绍 系统概述 核心功能 具体实现截图 1. 首页功能 2. 旧物信息功能 3. 网站公告功能 4. 用户管理功能&#xff08;管理员端&#xff09; 5. 置换交易管理功能 技术栈 后端框架SpringBoot 前端框架Vue 持久层框架MyBatis-Plus …

新书速览|循序渐进Spark大数据应用开发

《循序渐进Spark大数据应用开发》 本书内容 《循序渐进Spark大数据应用开发》结合作者一线开发实践&#xff0c;循序渐进地介绍了新版Apache Spark 3.x的开发技术。全书共10章&#xff0c;第1章和第2章主要介绍Spark的基本概念、安装&#xff0c;并演示如何编写最简单的Spark程…

一道算法期末应用题及解答

1&#xff0e;印刷电路板布线区划分成为n m 个方格&#xff0c;确定连接方格a 到方格b 的最短布线方案。 在布线时&#xff0c;只能沿直线或者直角布线&#xff0c;为避免交叉&#xff0c;已经布线的方格做了封锁标记&#xff0c;其他线路不允许穿过被封锁的方格&#xff0c;某…

2024内科学综合类科技核心期刊汇总

在已经公布的中国科技核心期刊目录&#xff08;2024年版&#xff09;中&#xff0c;5本内科学综合类期刊入选。常笑医学整理了这5本科技核心期刊的详细参数&#xff0c;以及投稿信息&#xff0c;供大家在论文投稿时参考&#xff0c;有需要的赶紧收藏&#xff01; 1.《临床内科…

【网络】Socket编程TCP/UDP序列化和反序列化理解应用层(C++实现)Json::Value

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;计算机网络原理_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.基于Socket的UDP和TCP编程介绍 1.1 基本TCP客户—服务器程序设计基本框架 ​编辑1.2 基本UDP客户—服务器程序设计基本框…

Spring MVC——针对实习面试

目录 Spring MVC什么是Spring MVC&#xff1f;简单介绍下你对Spring MVC的理解&#xff1f;Spring MVC的优点有哪些&#xff1f;Spring MVC的主要组件有哪些&#xff1f;Spring MVC的工作原理或流程是怎样的&#xff1f;Spring MVC常用注解有哪些&#xff1f; Spring MVC 什么是…

硬件工程师之电子元器件—二极管(10)之可变电容和TVS二极管

写在前面 本系列文章主要讲解二极管的相关知识&#xff0c;希望能帮助更多的同学认识和了解二极管。 若有相关问题&#xff0c;欢迎评论沟通&#xff0c;共同进步。(*^▽^*) 二极管 25. 齐纳二极管的动态阻抗 齐纳阻抗是齐纳二极管在传导电流时的等效串联电阻&#xff08;E…

2024-11-19 树与二叉树

一、树的定义和基本语术 1.基本概念&#xff1a;从根节点出发&#xff0c;依次长出各个分支&#xff0c;各个分支也能长出下级分支。&#xff08;根节点无前驱&#xff0c;叶无后继&#xff09;除根节点外&#xff0c;任何一个结点有且仅有一个前驱。 2.树的基本概念&#xff…

【金融风控项目-08】:特征构造

文章目录 1.数据准备1.1 风控建模特征数据1.2 人行征信数据1.3 据之间的内在逻辑 2 样本设计和特征框架2.1 定义观察期样本2.2 数据EDA(Explore Data Analysis)2.3 梳理特征框架 3 特征构造3.1 静态信息和时间截面特征3.2 未来信息问题3.2.1 未来信息案例3.2.2 时间序列特征的未…

docker基础

一 docker整体架构 docker镜像&#xff08;image&#xff09; docker hub类似于maven远程仓库地址&#xff1a; https://hub.docker.com/ 该地址用于搜索并下载地址。 镜像下载命令&#xff1a; docker pull imagename 比如&#xff1a;docker pull to…

Qt 元对象系统

Qt 元对象系统 Qt 元对象系统1. 元对象的概念2. 元对象系统的核心组件2.1 QObject2.2 Q_OBJECT 宏2.3 Meta-Object Compiler (MOC) 3. 信号与槽3.1 基本概念信号与槽的本质信号和槽的关键特征 3.2 绑定信号与槽参数解析断开连接 3.3 标准信号与槽查找标准信号与槽使用示例规则与…

Lua如何连接MySQL数据库?

大家好&#xff0c;我是袁庭新。使用Lua语言如何来连接数据库呢&#xff1f;新哥这篇文章给你安排上。 1 LuaSQL概述 LuaSQL是一个轻量级的Lua到数据库管理系统&#xff08;DBMS&#xff09;的接口库&#xff0c;由Kepler Project维护&#xff0c;且是开源的。它提供了一个简…

高级指南:全面解析线上服务器CPU占用过高问题及其解决方案

文章目录 拿到CPU占用高的进程ID通过进程ID拿到CPU占用高的线程ID将线程ID转换为十六进制jstack分析线程栈信息 CPU占用过高的时候要先找出到底是哪个进程下的线程占用内存过高了。 我在线上预先写了一个Java程序&#xff0c;Test.java用于本篇文章实验所用。模拟CPU占用过高时…

单片机智能家居火灾环境安全检测-分享

目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 电路图采用Altium Designer进行设计&#xff1a; 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 传统的火灾报警系统大多依赖于简单的烟雾探测器或温度传感器&#xff0c;…

打造网页版Ubuntu环境:群晖NAS部署docker-webtop与远程访问指南

文章目录 前言1. 下载Docker-Webtop镜像2. 运行Docker-Webtop镜像3. 本地访问网页版Linux系统4. 群晖NAS安装Cpolar工具5. 配置异地访问Linux系统6. 异地远程访问Linux系统7. 固定异地访问的公网地址 前言 本文旨在详细介绍如何在群晖NAS部署docker-webtop&#xff0c;并结合c…

Python轴承故障诊断 (19)基于Transformer-BiLSTM的创新诊断模型

往期精彩内容&#xff1a; Python-凯斯西储大学&#xff08;CWRU&#xff09;轴承数据解读与分类处理 Pytorch-LSTM轴承故障一维信号分类(一)-CSDN博客 Pytorch-CNN轴承故障一维信号分类(二)-CSDN博客 Pytorch-Transformer轴承故障一维信号分类(三)-CSDN博客 三十多个开源…

STM32设计学生宿舍监测控制系统-分享

目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 电路图采用Altium Designer进行设计&#xff1a; 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 本项目旨在利用STM32单片机为核心&#xff0c;结合传感器技术、无线通信技…