学习SpringBoot笔记--知识点(1)

目录

SpringBoot介绍

创建一个最基础的springbooot项目

使用Spring Initializr创建springboot项目

Spring Boot 自动配置机制

SpringBoot常用注解

1.组件注册

2.条件注解

3.属性绑定

SpringBoot自动配置流程​编辑

学习SpringBoot的方法

​编辑

SpringBoot日志配置

日志格式:

自定义日志格式:

使用日志:

指定日志级别:

日志分组:​编辑

日志文件输出:

日志归档和切割:(默认开启)

自定义日志系统:​编辑

切换默认日志系统:

SpringBoot Web开发

静态资源

WebMvcAutoConfiguration自动配置类分析

默认配置

自定义静态资源规则

路径匹配

内容协商

自定义数据格式返回

WebMvcConfigurationSupport

模板引擎

Thymeleaf整合

使用​编辑

SpringBoot开发工具

国际化

错误处理

MVC处理机制:

boot机制:

最佳实战

​编辑

嵌入式容器

Web新特性

Problemdetails

函数式Web(估计用不到)


版本要求

SpringBoot介绍

SpringBoot 能够帮我们简单、快速地创建一个独立的、生产级别的Spring应用

特性:

  • 快速创建独立Spring应用
  • 直接嵌入tomcat、jetty或Undertow等Servlet容器,无需部署war包
  • 提供可选的starter,简化应用整合
  • 按需自动配置Spring以及第三方库
  • 提供生产级别特性:如 监控指标、健康检查(k8s)、外部化配置等
  • 无代码生成,无xml

创建一个最基础的springbooot项目

1.创建项目

2.将父工程设置为spring-boot-starter-parent,导入springboot web 开发的基础依赖:spring-boot-starter-web,设置springboot打包插件:spring-boot-maven-plugin

<?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.qiu</groupId><artifactId>boot-1-project</artifactId><version>1.0-SNAPSHOT</version>
<!--    springboot项目必须继承 spring-boot-starter-parent--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.5</version></parent><dependencies>
<!--        web开发的场景启动器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins>
<!--            springboot项目的打包插件--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

3.编写启动类,springboot web项目可以直接运行该类来启动项目,不需要tomcat等服务器,因为springboot已经内置服务器。

//启动类注解
@SpringBootApplication
public class SpringMain {public static void main(String[] args) {//固定代码:SpringApplication.run(启动类的类对象,main函数的参数);SpringApplication.run(SpringMain.class,args);}
}

4.编写服务

@RestController
// ==  Controller(将该类放入ioc容器) + ResponseBody(以数据格式返回,不添加该注解会经过视图解析器)
public class HelloController {//请求映射:/hello的请求会调用该方法@RequestMapping("hello")public String hello(){//将数据返回return "hello spring boot3 !";}
}

5.启动服务

6.访问服务

7.将项目打包

8.运行项目:把jar包放到有java环境的服务器上就可以直接启动(记得把项目停掉)

9.springboot可以不在源码修改配置文件,在jar包目录下创建一个 .properties 配置文件就可以覆盖配置,还可以创建config文件夹,把配置文件放进去,优先级更高


使用Spring Initializr创建springboot项目

创建服务并启动项目:

@RestController
public class HelloController {@RequestMapping("hello")public String hello(){return "hello spring init";}}


Spring Boot 自动配置机制

  • 自动配置的Tomcat,SpringMVC等
    • springboot自动配置DispatcherServlet、ViewResolver、CharacterEncodingFilter等组件
    • 如果需要哪些组件,只需要把启动器导入,就自动配置到ioc容器
    • 可以使用以下代码查看配置的组件
public static void main(String[] args) {//获取ioc容器ConfigurableApplicationContext run = SpringApplication.run(Boot2ProjectApplication.class, args);//查看所有组件//springboot自动配置好核心组件for (String name : run.getBeanDefinitionNames()) {System.out.println(name);}}
  • 默认的包扫描规则
    • 默认扫描启动类的目录及子目录
    • 可以@SpringBootApplication(scanBasePackages="com.qiu")
    • 也可以@ComponentScan("com.qiu")
  • 配置默认值
    • 配置文件中的所有配置项都是跟某个类的对象值一一对应的。
    • 在application.properties中按住ctrl点击对应的配置项可以跳转到对应的类。
    • 这样的类叫做配置属性类。
    • 比如:ServerProperties包含所有Tomcat服务器相关的配置 , MultipartProperties包含所有文件上传相关的配置。
  • 按需加载自动配置
    • 当导入启动器,如:spring-boot-starter-web时,启动器除了会导入相关功能的依赖,还会导入一个spring-boot-starter
    • spring-boot-starter是所有启动器的启动器,是基础核心starter
    • spring-boot-starter导入了spring-boot-autoconfigure,这个包有所有启动器的AutoConfiguration(自动配置类)
    • 但不会全部开启,只有导入对应的启动器时才会开启相应的自动配置

SpringBoot常用注解

SpringBoot不再使用XML配置方式,使用全注解驱动

1.组件注册

@Configuration:在类上添加,表明是个配置类,替代配置文件。

@SpringBootConfiguration:与@Configuration功能相同,更见名知意。

@Bean:在配置类下的方法上添加,替代<Bean>标签。

@Controller、@Service、@Repository、@Component:在类上使用,表明把这个类放到ioc容器。

@Import:可以导入任意类,当我们需要把第三方的组件放到ioc容器中,除了使用@Bean,还可以直接在配置类上使用@Import( … .class) 将组件放到ioc容器中。

@ComponentScan:在配置类上使用@ComponentScan("路径"),来扫描路径下的组件放到ioc容器中。

2.条件注解

@ConditionalOnXxx:

@ConditionOnClass:如果类路径中存在这个类,则触发指定行为

@ConditionOnMissingClass:如果类路径中不存在这个类,则触发指定行为

@ConditionOnBean:如果容器中存在这个Bean,则触发指定行为

@ConditionOnMissingBean:如果容器中不存在这个Bean,则触发指定行为

解释:当ioc容器中有FastsqlException组件就把Cat类放到ioc容器,没有就把Dog类放到ioc容器中。

如果该注解放到配置类上,这个配置类才生效。

3.属性绑定

@ConfigurationProperties

@EnableConfigurationProperties

将容器的任意组件的属性值和配置文件的配置项的值进行绑定。

示例:编写application配置文件

student.id=1
student.name=qiu
student.age=22

创建pojo类并放到ioc容器


@Component
public class Student {@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}Integer id;String name;Integer age;
}

只要类中属性与配置文件的配置项相同,就在类上添加注解(类属性要有set和get方法)

@ConfigurationProperties(prefix = "student")
@Component
public class Student {@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}Integer id;String name;Integer age;
}

这样启动服务后,就会自动给组件赋值

EnableConfigurationProperties(Student.class)功能:(主要用在第三方)

1.开启Student组件的属性绑定

2.默认把该组件放到ioc容器中


SpringBoot自动配置流程


学习SpringBoot的方法

示例:

1、导入redis的启动器

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

2、导入启动器后就会有相应的自动配置类:RedisAutoConfiguration

     输入 ctrl + n 搜索可查看

3、在类上可以看到@EnableConfigurationProperties({RedisProperties.class}),这个注解开启了RedisProperties类的属性绑定,ctrl + 左键 查看

4、在类上看到@ConfigurationProperties( prefix = "spring.data.redis" ),就知道在配置文件对应配置项

5、在RedisAutoConfiguration中可以看到把哪些Bean放到ioc容器中,可以修改配置或覆盖


SpringBoot日志配置

日志接口日志实现类

JCL(Jakarta Commons Logging)

SLF4j(Simpple Logging Facade for Java)

jboss-logging

Log4j

JUL(java.util.logging)

Log4j2

Logback

Spring5以后把commons-logging作为内部日志,但支持jul,log4j2,logback。默认使用logback

日志格式:

2024-03-23T01:01:09.925+08:00  INFO 27188 --- [boot-2-project] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
  • 默认格式:
    • 时间和日期:毫秒级精度
    • 日志级别:ERROR,WARN,INFO,DEBUG ,TRACE
    • 进程ID
    • ---:信息分割符
    • 线程名:使用[]包含
    • Logger名:通常是产生日志的类名
    • 消息:日志记录的内容

自定义日志格式:

%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n

使用日志:

方法1:从日志工厂获得记录当前类的记录器(一个类可以有一个记录器),调用方法

方法2:在类使用@Slf4j注解(需要添加lombok依赖),它会在底层自动为这个类注入log属性,使用log打印日志。

指定日志级别:

Springboot默认所有日志只要没有指定日志级别就使用root的默认级别(info)或设置的级别:

logging.level.root = debug

日志内容可以使用占位符:

log.info("a:{},b:{}",a,b);

指定某个类或包的日志级别:

logging.level.com.qiu.boot2project.controller = info

日志分组:

日志文件输出:

指定文件名:只写名字生成到当前位置

logging.file.name=D:\\logging\\file.log

指定文件路径:日志文件名默认为spring.log

logging.file.path=D:\\logging\\

同时指定文件名和文件路径只看文件名

日志归档和切割:(默认开启)

# 归档    切割
# LOG_FILE 就是 自己配置的文件名      yyyy-MM-dd 时间       i 当天的第几个文件
# max-file-size 只要文件超过了1MB 切割下一个文件
logging.logback.rollingpolicy.file-name-pattern=${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
logging.logback.rollingpolicy.max-file-size=1MB

只有logback才能直接配置,如果要使用其他日志系统,需要自行配置(log4j2需要添加log4j2.xml或log4j2-spring.xml)

自定义日志系统:

可以自行编写logback.xml或logback-spring.xml配置文件,这时springboot会读取这个配置文件,不使用默认的日志。

<?xml version="1.0" encoding="UTF-8"?><!-- 配置文件修改时重新加载,默认true -->
<configuration scan="true"><!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--><property name="CATALINA_BASE" value="logs"></property><!-- 控制台输出 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder charset="UTF-8"><!-- 输出日志记录格式 --><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><!-- 第一个文件输出,每天产生一个文件 --><appender name="FILE1" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 输出文件路径+文件名 --><fileNamePattern>${CATALINA_BASE}/aa.%d{yyyyMMdd}.log</fileNamePattern><!-- 保存30天的日志 --><maxHistory>30</maxHistory></rollingPolicy><encoder charset="UTF-8"><!-- 输出日志记录格式 --><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><!-- 第二个文件输出,每天产生一个文件 --><appender name="FILE2" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${CATALINA_BASE}/bb.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${CATALINA_BASE}/bb.%d{yyyyMMdd}.log</fileNamePattern><maxHistory>30</maxHistory></rollingPolicy><encoder charset="UTF-8"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><appender name="CUSTOM" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${CATALINA_BASE}/custom.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- daily rollover --><fileNamePattern>${CATALINA_BASE}/custom.%d{yyyy-MM-dd}.log</fileNamePattern><!-- keep 30 days' worth of history --><maxHistory>30</maxHistory></rollingPolicy><encoder charset="UTF-8"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><!-- 设置日志输出级别 --><root level="ERROR"><appender-ref ref="CONSOLE" /></root><logger name="file1" level="DEBUG"><appender-ref ref="FILE1" /></logger><logger name="file1" level="INFO"><appender-ref ref="FILE2" /></logger><!-- 自定义logger --><logger name="custom" level="INFO"><appender-ref ref="CUSTOM" /></logger>
</configuration>

切换默认日志系统:

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j</artifactId></dependency>

SpringBoot Web开发

依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

最佳实战:


静态资源

WebMvcAutoConfiguration自动配置类分析

1.生效条件:

@AutoConfiguration(after = {DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class}
)//在这三个自动配置类后面开始自动配置
@ConditionalOnWebApplication(type = Type.SERVLET
)//如果是web应用,并且还得是servlet类型(还有Reactive 响应式web应用)才能生效
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})//当存在这些Bean才生效
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})//当没有这个Bean才生效
@AutoConfigureOrder(-2147483638)//优先级
@ImportRuntimeHints({WebResourcesRuntimeHints.class})
public class WebMvcAutoConfiguration {

2.效果:

1.放了两个Bean:FormContentFilter 和 HiddenHttpMethodFilter

  • HiddenHttpMethodFilter:页面表单提交Rest请求(GET,POST,PUT,DELETE),不然表单只能发送GET和POST
  • FormContentFilter:表单内容Filter,不然只有GET(URL后面)和POST(请求体)能携带数据,PUT和DELETE请求体数据会被忽略。

2.给容器放了WebMvcConfigurer组件:给SpringMvc添加各种定制功能

 @Configuration(proxyBeanMethods = false)@Import({EnableWebMvcConfiguration.class})@EnableConfigurationProperties({WebMvcProperties.class, WebProperties.class})@Order(0)public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {

 3.WebMvcConfigurer


4.静态资源的规则源码addResourceHandlers

public void addResourceHandlers(ResourceHandlerRegistry registry) {if (!this.resourceProperties.isAddMappings()) {logger.debug("Default resource handling disabled");} else {//规则1this.addResourceHandler(registry, this.mvcProperties.getWebjarsPathPattern(), "classpath:/META-INF/resources/webjars/");//规则2this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {registration.addResourceLocations(this.resourceProperties.getStaticLocations());if (this.servletContext != null) {ServletContextResource resource = new ServletContextResource(this.servletContext, "/");registration.addResourceLocations(new Resource[]{resource});}});}}

规则1:访问 /webjars/** 就到 classpath:/META-INF/resources/webjars/ 下找资源。

             maven导入依赖,依赖jar包下的静态资源可以通过/webjars/访问

规则2:访问 /** 就到 "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" 这些下找资源。

规则3:静态资源默认都有缓存规则的设置

  • 所有缓存的配置修改,在配置文件的 spring.web
  • cachePeriod:缓存周期:多久不用找服务器要新的,默认没有,以秒为单位
  • cacheControl:HTTP缓存控制
  • useLastModified:是否使用最后一次修改,配合http cache规则

                如果浏览器访问了一个静态资源,如果服务器这个资源没有发生变化,下次访问直接让浏览器用自己缓存中的东西,而不是给服务器发请求。

//addResourceHandler方法内部
registration.setCachePeriod(this.getSeconds(this.resourceProperties.getCache().getPeriod()));
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());

5.EnableWebMvcConfiguration源码

@Configuration(proxyBeanMethods = false)@EnableConfigurationProperties({WebProperties.class})public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {

 这个类继承了WebMvcConfigurationSupport,就是SpringBoot给容器中放了WebMvcConfigurationSupport组件。

如果我们自己放了这个组件,SpringBoot的WebMvcAutoConfiguration都不会生效;但他自己是在自动配置类生效后放的,不矛盾。

类下有方法WelcomePageHandlerMapping:只要静态资源路径内有index.html,项目启动就默认访问。


默认配置

静态资源映射

  • 访问 /webjars/** 就到 classpath:/META-INF/resources/webjars/ 下找资源。
    • maven导入依赖,依赖jar包下的静态资源可以通过/webjars/访问
  • 访问 /** 就到 "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" 这些下找资源。

静态资源缓存

静态资源默认都有缓存规则的设置

  • 所有缓存的配置修改,在配置文件的 spring.web
  • cachePeriod:缓存周期:多久不用找服务器要新的,默认没有,以秒为单位
  • cacheControl:HTTP缓存控制
  • useLastModified:是否使用最后一次修改,配合http cache规则

欢迎页

只要静态资源路径内有index.html,项目启动就默认访问。

Favicon

每次浏览器请求网站时,都会请求 /favicon.ico,只要静态资源路径下有该图标就会返回。

 缓存的一些配置


自定义静态资源规则

自定义静态资源路径,自定义缓存规则

1.配置方式

  • spring.mvc:
    • 静态资源访问前缀路径(你想要访问静态资源要在浏览器输入的路径的前缀)
  • spring.web:
    • 静态资源在服务器的位置前缀
    • 静态资源缓存策略

# 自定义webjars路径前缀
spring.mvc.webjars-path-pattern=/wj/**
# 静态资源访问路径前缀
spring.mvc.static-path-pattern=/static/**
# 自定义静态资源在服务器的位置
spring.web.resources.static-locations=classpath:/a/,classpath:/b/,classpath:/static/

2.代码方式

创建一个配置类,实现WebMvcConfigurer接口,不要添加@EnableWebMvc,它会禁用boot的springMvc自动配置。

@Configuration
public class MyConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {//保留默认配置WebMvcConfigurer.super.addResourceHandlers(registry);//自己写registry.addResourceHandler("/static/**").addResourceLocations("classpath:/a/","classpath:/b/").setCacheControl(CacheControl.maxAge(1180, TimeUnit.SECONDS));}
}

路径匹配

Spring5.3之前只支持AntPathMatcher,现在提供了PathPatternParser策略,并且可以指定使用哪种策略。默认使用新版策略。


内容协商

1.基于请求头:在请求头添加:Accept:application/数据格式(json,xml)

2.基于请求参数:在请求参数中添加format=数据格式(需要开启)

# 使用参数进行内容协商
spring.mvc.contentnegotiation.favor-parameter=true 
# 自定义参数名 ,默认为format
spring.mvc.contentnegotiation.parameter-name=myparam

SpringBoot会自动就数据转换为对应的数据格式

默认支持把数据对象写成json,因为web启动器默认导入了jackson处理json的包:jackcon-core。

jackson也支持把数据对象写成xml,要导入xml相关的处理依赖

        <dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId></dependency>

在对象上添加注解

这样就可以根据请求返回xml数据对象了。

@Data
@JacksonXmlRootElement
public class People {private String name;private Integer sex;
}
自定义数据格式返回

内容协商原理-HttpMessageConverter

1.@ResponseBody 由 HttpMessageConverter 处理

2.WebMvcAutoConfiguration提供几个默认HttpMessageConverters

系统里功能有限,只能返回json或普通数据,要返回新的类型需要增加新的HttpMessageConverter。


WebMvcConfigurationSupport

提供了很多的默认配置

如果手动把它放到ioc容器,SpringBoot关于web的自动配置就会失效

该类判断系统中是否有相应的包,如果有,就加入相应的HttpMessageConverter,但顶多也就json和xml等,向yaml等依然不支持。

static {ClassLoader classLoader = WebMvcConfigurationSupport.class.getClassLoader();romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader);jaxb2Present = ClassUtils.isPresent("jakarta.xml.bind.Binder", classLoader);jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);jackson2CborPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader);gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader);jsonbPresent = ClassUtils.isPresent("jakarta.json.bind.Jsonb", classLoader);kotlinSerializationCborPresent = ClassUtils.isPresent("kotlinx.serialization.cbor.Cbor", classLoader);kotlinSerializationJsonPresent = ClassUtils.isPresent("kotlinx.serialization.json.Json", classLoader);kotlinSerializationProtobufPresent = ClassUtils.isPresent("kotlinx.serialization.protobuf.ProtoBuf", classLoader);}

操作

想要自定义数据格式,只需要编写WebMvcConfigurer接口的实现类提供的configureMessageConverters底层,修改底层的MessageConverter即可。

示例:yaml类型

添加依赖: 

<!--		支持返回yaml包--><dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-yaml</artifactId></dependency>

配置application文件:

# 增加一种新的内容类型
spring.mvc.contentnegotiation.media-types.yaml = application/yaml

编写一个格式转换器:

public class MyYamlHttpMessageConverter extends AbstractHttpMessageConverter<Object> {private ObjectMapper objectMapper = null;//该属性就是来把对象转成yamlpublic MyYamlHttpMessageConverter(){YAMLFactory yamlFactory = new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER/*取消yaml的文档分隔符*/);this.objectMapper = new ObjectMapper(yamlFactory);}//支持把什么类型写成yaml格式@Overrideprotected boolean supports(Class<?> clazz) {//可以在此判断return true;}@Override //@RequestBodyprotected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {return null;}@Override //@ResponseBody 怎么把对象写成对应格式protected void writeInternal(Object methodReturnValue, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
//        OutputStream body = outputMessage.getBody();
//        try {
//            this.objectMapper.writeValue(body,methodReturnValue);
//        }finally {
//            body.close();
//        }//try-with写法,自动关流try (OutputStream os = outputMessage.getBody()){this.objectMapper.writeValue(os,methodReturnValue);}}
}

把转换器和配置文件设置的类型关联起来:

转换器类继承的抽象类的构造方法可以传入mediatype,在传入的mediatype可以配置和配置文件设置的媒体类型一样的属性,这样两者就关联起来了。

在转换器的构造方法修改:

public MyYamlHttpMessageConverter(){//告诉springboot这个类型转换器支持哪种媒体类型super( new MediaType("application", "yaml", Charset.forName("UTF-8")));YAMLFactory yamlFactory = new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER/*取消yaml的文档分隔符*/);this.objectMapper = new ObjectMapper(yamlFactory);}

 把转换器配置到springboot:

@Configuration
public class MyConfig implements WebMvcConfigurer {@Override   //配置一个能把对象转换为yaml的messageConverterpublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(new MyYamlHttpMessageConverter());}
}

模板引擎

由于SpringBoot使用嵌入式Servlet容器,默认不能使用JSP。需要服务器页面渲染,优先考虑使用模板引擎。

模板引擎默认放到 /src/main/resources/templates

SpringBoot包含以下模板引擎的自动配置:

  • FreeMarker
  • Groovy
  • Thymeleaf(推荐)官网:Thymeleaf
  • Mustache 
Thymeleaf整合

导入启动器:

		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>

自动配置原理:

在ThymeleafAutoConfiguration下:

  • 将属性与配置文件下 spring.thymeleaf 绑定
  • 设置前缀 classpath:/templates/ 
  • 设置后缀 .html 

SpringBoot如果整合了Thymeleaf,默认是到 classpath:/templates/下找文件

编写服务:

//这时要返回页面,不能使用RestController
@Controller
public class WelcomeController {//请求路径:localhost:8080/welcome?name=qiu//就是name参数来填写到要返回的页面上@GetMapping("welcome")public String welcome(String name, Model model){//将msg:name放到model中,在模板引擎中就可以直接使用msg映射name的值model.addAttribute("msg",name);//返回页面的话,由于整合了Thymeleaf,将返回的字符串与设置的前后缀拼接在访问器中搜索并返回//    前缀(默认:classpath:/templates/) + welcome(返回字符串) + 后缀(默认:.html)return "welcome";}
}

在 \src\main\resources\templates 下创建文件 welcome.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--                th:... 是 Thymeleaf --><h1>你好:<span th:text="${msg}"></span></h1>
</body>
</html>

启动服务访问:localhost:8080/welcome?name=qiu


使用

 


SpringBoot开发工具

导入SpringBoot提供的依赖

<!--		热启动功能--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency>

修改代码或页面后按 ctrl + f9, 项目就热启动了。

如果修改的是java代码,最好重启项目,不然可能有一些bug。


国际化

 在resources下创建文件:messages.properties,messages_zh_CN.properties,messages_en_US.properties。

idea会自动识别形成以下目录:

国际化要成功使用,项目编码要是UTF-8:File->Settings->搜索 file encodings

messages.properties:

login=Login
sign=Sign-Up

messages_zh_CN.properties:

login=登录
sign=注册

messages_en_US.properties:

login=Login
sign=Sign-Up-US

在模板中:

<!--    会根据当前状态使用中文或者英文--><button th:text="#{login}"></button><button th:text="#{sign}"></button>


错误处理

错误处理的自动化配置在ErrorMvcAutoConfiguration中,两大核心机制:

1.SpringBoot会自适应处理错误,响应页面或JSON数据

2.SpringMVC的错误处理机制仍然保留,MVC处理不了才会交给boot处理

MVC处理机制:

可以在当前controller上添加处理方法:

    @ResponseBody@ExceptionHandler(Exception.class)public String handlerException(Exception e){System.out.println("异常处理代码");return e.getMessage();}

也可以创建一个异常处理类:

@ControllerAdvice   //这个类集中处理所有controller发生的错误
public class GlobaExceptionHandler {@ResponseBody@ExceptionHandler(Exception.class)public String handlerException(Exception e){System.out.println("异常处理");return e.getMessage();}
}

如果MVC机制无法解决,就提交boot机制处理。

boot机制:

boot会默认将MVC无法处理的异常转发到项目路径为: /error 下 ,boot底层设计了一个BasicErrorController 处理请求,server.error.path不修改默认为 /error 。

@Controller
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class BasicErrorController extends AbstractErrorController {

在该controller下,会先判断请求的是页面和JSON数据

如果是JSON:

  • boot封装了JSON格式的错误信息:DefaultErrorAttributes
  • 当发生JSON请求错误时,将错误信息放到DefaultErrorAttributes中并返回

如果是页面:

  • 如果发生了500,404,503等错误
    • 如果有模板引擎,默认返回classpath:/templates/error/错误码.html
    • 如果没有,默认返回 静态资源下的错误码.html
  • 如果没有匹配到错误码,就模糊匹配(4xx.html或5xx.html)
    • 如果有模板引擎,默认返回classpath:/templates/error/5xx.html(还真是5xx.html或4xx.html)
    • 如果没有,默认返回 静态资源下的5xx.html
  • 否则返回templates下的error.html(templates/error.html)
  • 如果templates没有error.html,返回SpringBoot自己的默认error页面
最佳实战

嵌入式容器

SpringBoot关于嵌入式容器的自动化配置为:ServletWebServerFactoryAutoConfiguration

SpringBoot默认使用Tomcat为内置Servlet容器。

SpringBoot支持3种Servlet容器:

  • Tomcat(默认)
  • Jetty
  • Undertow

SpringBoot关于各个容器的配置类以 server.容器 为前缀:

server.tomcat.accept-count=100
server.jetty.accesslog.append=false

要替换SpringBoot的Servlet容器方法:

  • 在导入web启动器时手动切换:
		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jetty</artifactId></dependency>

Web新特性

Problemdetails

错误信息返回新格式

在web自动化配置中将 ProblemDetailsExceptionHandler 放到ioc容器中:

    //web自动化配置类static class ProblemDetailsErrorHandlingConfiguration {ProblemDetailsErrorHandlingConfiguration() {}@Bean@ConditionalOnMissingBean({ResponseEntityExceptionHandler.class})@Order(0)ProblemDetailsExceptionHandler problemDetailsExceptionHandler() {return new ProblemDetailsExceptionHandler();}}//ProblemDetailsExceptionHandler源码@ControllerAdvice//异常处理类final class ProblemDetailsExceptionHandler extends ResponseEntityExceptionHandler {ProblemDetailsExceptionHandler() {}}

它来处理以下异常:

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class, HttpMediaTypeNotSupportedException.class, HttpMediaTypeNotAcceptableException.class, MissingPathVariableException.class, MissingServletRequestParameterException.class, MissingServletRequestPartException.class, ServletRequestBindingException.class, MethodArgumentNotValidException.class, NoHandlerFoundException.class, AsyncRequestTimeoutException.class, ErrorResponseException.class, ConversionNotSupportedException.class, TypeMismatchException.class, HttpMessageNotReadableException.class, HttpMessageNotWritableException.class, BindException.class})

如果系统出现这些异常,SpringBoot以 RFC 7807 规范方式返回数据。

不过该功能默认关闭,需要在配置文件中手动开启:

spring.mvc.problemdetails.enabled=true

函数式Web(估计用不到)

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

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

相关文章

2015年认证杯SPSSPRO杯数学建模A题(第一阶段)绳结全过程文档及程序

2015年认证杯SPSSPRO杯数学建模 A题 绳结 原题再现&#xff1a; 给绳索打结是人们在日常生活中常用的技能。对登山、航海、垂钓、野外生存等专门用途&#xff0c;结绳更是必不可少的技能之一。针对不同用途&#xff0c;有多种绳结的编制方法。最简单的绳结&#xff0c;有时称…

PyCharm环境下Git与Gitee联动:本地与远程仓库操作实战及常见问题解决方案

写在前面&#xff1a;本博客仅作记录学习之用&#xff0c;部分图片来自网络&#xff0c;如需引用请注明出处&#xff0c;同时如有侵犯您的权益&#xff0c;请联系删除&#xff01; 文章目录 前言下载及安装GitGit的使用设置用户签名设置用户安全目录Git基本操作Git实操操作 Pyc…

SpringBoot+Vue前后端分离项目在Linux系统中基于Docker打包发布,并上传镜像到阿里镜像私仓

文章目录 SpringBootVue前后端分离项目在Linux系统中基于Docker打包发布&#xff0c;并上传镜像到阿里镜像私仓一、Java项目基于Docker打包发布1.打包应用&#xff0c;将打好的jar包放到我们的linux系统中2.新建dockerfile3.打包镜像4.测试运行5.上传镜像到阿里云免费私仓 二、…

Webpack生成企业站静态页面 - 项目搭建

现在Web前端流行的三大框架有Angular、React、Vue&#xff0c;很多项目经过这几年的洗礼&#xff0c;已经都 转型使用这三大框架进行开发&#xff0c;那为什么还要写纯静态页面呢&#xff1f;比如Vue中除了SPA单页面开发&#xff0c;也可以使用nuxt.js实现SSR服务端渲染&#x…

基于前端技术实现的全面预算编制系统

前言 在现代商业环境中&#xff0c;预测销售数据和实际成本是每个公司CEO和领导都极为重视的关键指标。然而&#xff0c;由于市场的不断变化&#xff0c;准确地预测和管理这些数据变得愈发具有挑战性。为了应对这一挑战&#xff0c;建立一个高效的系统来管理和审查销售数据的重…

hbase启动错误-local host is“master:XXXX“ destination is:master

博主的安装前提&#xff1a; zookeeper安装完成&#xff0c;且启动成功 hdfs高可用安装&#xff0c;yarn高可用安装&#xff0c;且启动成功 报错原因&#xff1a;端口配置不对 解决方案&#xff1a; 输入&#xff1a;hdfs getconf -confKey fs.default.name 然后把相应的…

考研数学一——概率论真题——自我总结题型整理(总分393)

系列文章目录 终于考完研了&#xff0c;本人考的是南京航空航天大学的仪器科学与技术&#xff0c;英一数一电路&#xff0c;以下是成绩单&#xff1a; 平时习惯整理自己的学习体系&#xff0c;以下是一个记录。 其实&#xff0c;每个人都应该训练&#xff0c;看到某一类题目…

2024/03/25(C++·day1)

一、思维导图 二、练习 练习一 定义自己的命名空间&#xff0c;其中有string类型的变量&#xff0c;再定义两个函数&#xff0c;一个函数完成字符串的输入&#xff0c;一个函数完成求字符串长度&#xff0c;再定义一个全局函数完成对该字符串的反转 #include <iostream&g…

# vue刷新当前页面

vue刷新当前页面 背景 在项目开发中遇到了需要刷新当前页面的场景。中途尝试了以下四种方法 1、this. f o r c e U p d a t e ( ) t h i s . forceUpdate() this. forceUpdate()this.forceUpdate() 是Vue.js中的一个方法&#xff0c;用于强制组件重新渲染&#xff0c;即使没有…

景联文科技上新高质量大模型训练数据!

在过去的一年中&#xff0c;人工智能领域呈现出了风起云涌的态势&#xff0c;其中模型架构、训练数据、多模态技术、超长上下文处理以及智能体发展等方面均取得了突飞猛进的发展。 在3月24日举办的2024全球开发者先锋大会的大模型前沿论坛上&#xff0c;上海人工智能实验室的领…

【Android】美团组件化路由框架WMRouter源码解析

前言 Android无论App开发还是SDK开发&#xff0c;都绕不开组件化&#xff0c;组件化要解决的最大的问题就是组件之间的通信&#xff0c;即路由框架。国内使用最多的两个路由框架一个是阿里的ARouter&#xff0c;另一个是美团的WMRouter。这两个路由框架功能都很强大&#xff0…

一篇文章,告别Flutter状态管理争论,问题和解决

起因 每隔一段时间&#xff0c;都会出现一个新的状态管理框架&#xff0c;最近在YouTube上也发现了有人在推signals, 一个起源于React的状态管理框架&#xff0c;人们总是乐此不疲的发明各种好用或者为了解决特定问题而产生的方案&#xff0c;比如Bloc, 工具会推陈出新&#x…

[Vue warn]: Invalid vnode type when creating vnode: false

如题&#xff0c;意思是创建vnode时&#xff0c;vnode类型无效:false。 根据右边的索引点进去&#xff0c;发现定位的是组件loading。搜索loading发现声明了变量loading&#xff0c;更改后问题消失。

【python】获取4K壁纸保存到本地文件夹【附源码】

图片信息丰富多彩&#xff0c;许多网站上都有大量精美的图片资源。有时候我们可能需要批量下载这些图片&#xff0c;而手动一个个下载显然效率太低。因此&#xff0c;编写一个简单的网站图片爬取程序可以帮助我们高效地获取所需的图片资源。 目标网站&#xff1a; 如果出现模…

物联网云组态是什么?部署物联网云组态有什么作用?

在信息化与工业化的深度融合进程中&#xff0c;物联网云组态以其独特的优势&#xff0c;正在成为企业数字化转型的重要工具。那么&#xff0c;物联网云组态究竟是什么呢&#xff1f;部署物联网云组态又能给企业带来哪些实质性的好处呢&#xff1f;今天&#xff0c;我们将围绕这…

vue 消息左右滚动(前后无缝衔接)

之前一直用vue-seamless-scroll&#xff0c;无奈此组件有两个缺点不满足实际效果&#xff1a;1&#xff09;标题过长被截取、2&#xff09;标题果断也会滚动&#xff0c;无奈我自己封装一个&#xff0c;满足此两个弊端&#xff0c;也能达到vue-seamless-scroll组件的功能&#…

AI:Nvidia官网人工智能大模型工具合集(文本生成/图像生成/视频生成)的简介、使用方法、案例应用之详细攻略

AI&#xff1a;Nvidia官网人工智能大模型工具合集(文本生成/图像生成/视频生成)的简介、使用方法、案例应用之详细攻略 目录 Nvidia官网人工智能大模型工具合集的简介 1、网站主要功能包括: Nvidia官网人工智能大模型工具合集的使用方法 1、SDXL-Turbo的使用 2、GEMMA-7B的…

详解 net user

net user 是 Windows 操作系统自带的一个命令行工具&#xff0c;用于管理和查询本地用户账户信息。在域环境中&#xff0c;它可以用于管理本地用户账户&#xff0c;但对域用户账户的操作能力有限&#xff0c;尤其是查看域账户锁定状态等功能。以下是 net user 命令的详解&#…

【学习】Web安全测试需要考虑哪些情形

一、数据加密 某些数据需要进行信息加密和过滤后才能在客户端和服务器之间进行传输&#xff0c;包括用户登录密码、信用卡信息等。例如&#xff0c;在登录某银行网站时&#xff0c;该网站必须支持SSL协议&#xff0c;通过浏览器访问该网站时&#xff0c;地址栏的http变成https…

中国中药有限公司邀您到场参观2024燕窝滋补品展

参展企业介绍 中国中药有限公司是中国医药集团有限公司&#xff08;简称“国药集团”&#xff09;的全资子公司&#xff0c;是国药集团中药产业板块的核心投资平台&#xff0c;也是中药一类新药、中药科技进步一等奖、中药保密品种——“人工麝香”全国总代理。 公司经营范围…