02-SpringBoot3Web开发
SpringBoot的
Web开发
能力,由SpringMVC
提供。
一、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 })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class) //容器中没有这个Bean,才生效。默认就是没有
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)//优先级
@ImportRuntimeHints(WebResourcesRuntimeHints.class)
public class WebMvcAutoConfiguration {
}
2. 效果
- 放了两个Filter:
a. HiddenHttpMethodFilter;页面表单提交Rest请求(GET、POST、PUT、DELETE)
b. FormContentFilter: 表单内容Filter,GET(数据放URL后面)、POST(数据放请求体)请求可以携带数据,PUT、DELETE 的请求体数据会被忽略 - 给容器中放了WebMvcConfigurer组件;给SpringMVC添加各种定制功能
a. 所有的功能最终会和配置文件进行绑定
b. WebMvcProperties: spring.mvc配置文件
c. WebProperties: spring.web配置文件
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class) //额外导入了其他配置
@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware{
}
3.静态资源规则源码
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
//1、
addResourceHandler(registry, this.mvcProperties.getWebjarsPathPattern(),
"classpath:/META-INF/resources/webjars/");
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
registration.addResourceLocations(resource);
}
});
}
- 规则一:访问: /webjars/**路径就去 classpath:/META-INF/resources/webjars/下找资源.
a. maven 导入依赖 - 规则二:访问: /**路径就去 静态资源默认的四个位置找资源
a.classpath:/META-INF/resources/
b.classpath:/resources/
c.classpath:/static/
d.classpath:/public/
- 规则三:静态资源默认都有缓存规则的设置
a. 所有缓存的设置,直接通过配置文件: spring.web
b. cachePeriod: 缓存周期; 多久不用找服务器要新的。 默认没有,以s为单位
c. cacheControl: HTTP缓存控制;
d. useLastModified:是否使用最后一次修改。配合HTTP Cache规则
如果浏览器访问了一个静态资源 index.js,如果服务这个资源没有发生变化,下次访问的时候就可以直接让浏览器用自己缓存中的东西,而不用给服务器发请求。
registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());
二、Web场景
2.1 自动配置
1、整合web场景
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2、引入了 autoconfigure功能
3、@EnableAutoConfiguration注解使用@Import(AutoConfigurationImportSelector.class)批量导入组件
4、加载 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中配置的所有组件
5、所有自动配置类如下
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
====以下是响应式web场景和现在的没关系======
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.ReactiveMultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration
================以上没关系=================
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
6、绑定了配置文件的一堆配置项
- 1、SpringMVC的所有配置 spring.mvc
- 2、Web场景通用配置 spring.web
- 3、文件上传配置 spring.servlet.multipart
- 4、服务器的配置 server: 比如:编码方式
2.2 默认效果
默认配置:
- 包含了 ContentNegotiatingViewResolver 和 BeanNameViewResolver 组件,方便视图解析
- 默认的静态资源处理机制: 静态资源放在 static 文件夹下即可直接访问
- 自动注册了 Converter,GenericConverter,Formatter组件,适配常见数据类型转换和格式化需求
- 支持 HttpMessageConverters,可以方便返回json等数据类型
- 注册 MessageCodesResolver,方便国际化及错误消息处理
- 支持 静态 index.html
- 自动使用ConfigurableWebBindingInitializer,实现消息处理、数据绑定、类型转化、数据校验等功能
重要:
- 如果想保持 boot mvc 的默认配置,并且自定义更多的 mvc 配置,如:interceptors, formatters, view controllers 等。可以使用@Configuration注解添加一个 WebMvcConfigurer 类型的配置类,并不要标注 @EnableWebMvc
- 如果想保持 boot mvc 的默认配置,但要自定义核心组件实例,比如:RequestMappingHandlerMapping, RequestMappingHandlerAdapter, 或ExceptionHandlerExceptionResolver,给容器中放一个 WebMvcRegistrations 组件即可
- 如果想全面接管 Spring MVC,@Configuration 标注一个配置类,并加上 @EnableWebMvc注解,实现 WebMvcConfigurer 接口
三、静态资源
3.1 默认规则
3.1.1 静态资源映射
静态资源映射规则在 WebMvcAutoConfiguration 中进行了定义:
- /webjars/** 的所有路径 资源都在 classpath:/META-INF/resources/webjars/
- /** 的所有路径 资源都在 classpath:/META-INF/resources/、classpath:/resources/、classpath:/static/、classpath:/public/
- 所有静态资源都定义了缓存规则。【浏览器访问过一次,就会缓存一段时间】,但此功能参数无默认值
a. period: 缓存间隔。 默认 0S;
b. cacheControl:缓存控制。 默认无;
c. useLastModified:是否使用lastModified头。 默认 false;
3.1.2 静态资源缓存
- 所有静态资源都定义了缓存规则。【浏览器访问过一次,就会缓存一段时间】,但此功能参数无默认值
a. period: 缓存间隔。 默认 0S;
b. cacheControl:缓存控制。 默认无;
c. useLastModified:是否使用lastModified头。 默认 false;
3.1.3 欢迎页
欢迎页规则在 WebMvcAutoConfiguration 中进行了定义:
- 在静态资源目录下找 index.html
- 没有就在 templates下找index模板页
3.1.4 Favicon
在静态资源目录下找 favicon.ico
3.1.5 缓存实验
server.port=9000
#1、spring.web:
# 1.配置国际化的区域信息
# 2.静态资源策略(开启、处理链、缓存)
#开启静态资源映射规则
spring.web.resources.add-mappings=true
#设置缓存
#spring.web.resources.cache.period=3600
##缓存详细合并项控制,覆盖period配置:
## 浏览器第一次请求服务器,服务器告诉浏览器此资源缓存7200秒,7200秒以内的所有此资源访问不用发给服务器请求,7200秒以后发请求给服务器
spring.web.resources.cache.cachecontrol.max-age=7200
#使用资源 last-modified 时间,来对比服务器和浏览器的资源是否相同没有变化。相同返回 304
spring.web.resources.cache.use-last-modified=true
3.2 自定义静态资源规则
自定义静态资源路径、自定义缓存规则
3.2.1 配置方式
spring.mvc: 静态资源访问前缀路径
spring.web:
- 静态资源目录
- 静态资源缓存策略
#1、spring.web:
# 1.配置国际化的区域信息
# 2.静态资源策略(开启、处理链、缓存)
#开启静态资源映射规则
spring.web.resources.add-mappings=true
#设置缓存
spring.web.resources.cache.period=3600
##缓存详细合并项控制,覆盖period配置:
## 浏览器第一次请求服务器,服务器告诉浏览器此资源缓存7200秒,7200秒以内的所有此资源访问不用发给服务器请求,7200秒以后发请求给服务器
spring.web.resources.cache.cachecontrol.max-age=7200
## 共享缓存
spring.web.resources.cache.cachecontrol.cache-public=true
#使用资源 last-modified 时间,来对比服务器和浏览器的资源是否相同没有变化。相同返回 304
spring.web.resources.cache.use-last-modified=true
#自定义静态资源文件夹位置
spring.web.resources.static-locations=classpath:/a/,classpath:/b/,classpath:/static/
#2、 spring.mvc
## 2.1. 自定义webjars路径前缀
spring.mvc.webjars-path-pattern=/jy/**
## 2.2. 静态资源访问路径前缀
spring.mvc.static-path-pattern=/static/**
四、路径匹配
Spring5.3
之后加入了更多的请求路径匹配的实现策略;以前只支持AntPathMatcher
策略, 现在提供了PathPatternParser
策略。并且可以让我们指定到底使用那种策略。
Ant风格路径用法
Ant 风格的路径模式语法具有以下规则:
- *:表示任意数量的字符。
- ?:表示任意一个字符。
- **:表示任意数量的目录。
- {}:表示一个命名的模式占位符。
- []:表示字符集合,例如[a-z]表示小写字母。
例如:
*.html
匹配任意名称,扩展名为.html的文件。/folder1/*/*.java
匹配在folder1目录下的任意两级目录下的.java文件。/folder2/**/*.jsp
匹配在folder2目录下任意目录深度的.jsp文件。/{type}/{id}.html
匹配任意文件名为{id}.html,在任意命名的{type}目录下的文件。
注意:Ant 风格的路径模式语法中的特殊字符需要转义,如:
- 要匹配文件路径中的星号,则需要转义为
\\*
。 - 要匹配文件路径中的问号,则需要转义为
\\?
。
模式切换
AntPathMatcher 与 PathPatternParser
- PathPatternParser 在 jmh 基准测试下,有 6~8 倍吞吐量提升,降低 30%~40%空间分配率
- PathPatternParser 兼容 AntPathMatcher语法,并支持更多类型的路径模式
- PathPatternParser “**” 多段匹配的支持仅允许在模式末尾使用
总结:
- 使用默认的路径匹配规则,是由 PathPatternParser 提供的
- 如果路径中间需要有 **,替换成ant风格路径
# 改变路径匹配策略:
# ant_path_matcher 老版策略;
# path_pattern_parser 新版策略;
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
五、内容协商
一套系统适配多端数据返回
多端内容适配
- SpringBoot 多端内容适配。
- 1.1. 基于请求头内容协商:(默认开启)
- 1.1.1. 客户端向服务端发送请求,携带HTTP标准的Accept请求头。
- 1.1.1.1. Accept: application/json、text/xml、text/yaml
- 1.1.1.2. 服务端根据客户端请求头期望的数据类型进行动态返回
- 1.1.1. 客户端向服务端发送请求,携带HTTP标准的Accept请求头。
- 1.2. 基于请求参数内容协商:(需要开启)
- 1.2.1. 发送请求 GET /projects/spring-boot?format=json
- 1.2.2. 匹配到 @GetMapping(“/projects/spring-boot”)
- 1.2.3. 根据参数协商,优先返回 json 类型数据【需要开启参数匹配设置】
- 1.2.4. 发送请求 GET /projects/spring-boot?format=xml,优先返回 xml 类型数据
- 1.1. 基于请求头内容协商:(默认开启)
效果演示
请求同一个接口,可以返回json和xml不同格式数据
- 引入支持写出xml内容依赖
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
- 标注注解
@JacksonXmlRootElement // 可以写出为xml文档
@Data
public class Person {
private Long id;
private String userName;
private String email;
private Integer age;
}
- 开启基于请求参数的内容协商
# 开启基于请求参数的内容协商功能。 默认参数名:format。 默认此功能不开启
spring.mvc.contentnegotiation.favor-parameter=true
# 指定内容协商时使用的参数名。默认是 format
spring.mvc.contentnegotiation.parameter-name=type
- 效果