尚硅谷SpringBoot3笔记 (二) Web开发
Spring Boot Web开发:24.Web开发-自动配置原理_哔哩哔哩_bilibili
1. Web场景
1.1 自动配置
整合web场景:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
包含配置项:
- 1、SpringMVC的所有配置
spring.mvc
- 2、Web场景通用配置
spring.web
- 3、文件上传配置
spring.servlet.multipart
- 4、服务器的配置
server
: 比如:编码方式
2. 默认效果
默认配置:
- 包含了 ContentNegotiatingViewResolver 和 BeanNameViewResolver 组件,方便视图解析
- 默认的静态资源处理机制: 静态资源放在 static 文件夹下即可直接访问
- 自动注册 Converter,GenericConverter,Formatter 组件,适配常见数据类型转换和格式化需求
- 支持 HttpMessageConverters,可以方便返回json等数据类型
- 注册 MessageCodesResolver,方便国际化及错误消息处理
- 支持 静态 index.html
- 自动使用ConfigurableWebBindingInitializer,实现消息处理、数据绑定、类型转化、数据校验等功能
spring boot Web开发场景的三种使用方式:
3. 静态资源规则(WebMvcAutoConfiguration)
所有的 静态资源配置类:
静态资源映射规则(固定的访问路径)在 WebMvcAutoConfiguration 中进行了定义:
- /webjars/** 的所有路径 资源都在 classpath:/META-INF/resources/webjars/
- /** 的所有路径 资源都在 classpath:/META-INF/resources/、classpath:/resources/、classpath:/static/、classpath:/public/
-
欢迎页规则在 WebMvcAutoConfiguration 中进行了定义:在静态资源目录下找 index.html,没有就在 templates下找index模板页
4. 自定义静态资源规则
- 1)第一种:修改配置文件
#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=/wj/**
## 2.2. 静态资源访问路径前缀
spring.mvc.static-path-pattern=/static/**
- 2)第二种:代码方式
- 容器中只要有一个 WebMvcConfigurer 组件。配置的底层行为都会生效
- @EnableWebMvc,禁用boot的默认配置
package org.example.boot.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.concurrent.TimeUnit;
@Configuration //这是一个配置类
public class MyConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//保留以前规则
//自己写新的规则。
registry.addResourceHandler("/static/**") // 设置url路径
.addResourceLocations("classpath:/a/","classpath:/b/") // 设置静态路径
.setCacheControl(CacheControl.maxAge(1180, TimeUnit.SECONDS)); // 设置缓存控制策略
}
}
使用@Bean加入重写的WebMvcConfigurer组件:
@Configuration //这是一个配置类,给容器中放一个 WebMvcConfigurer 组件,就能自定义底层
public class MyConfig /*implements WebMvcConfigurer*/ {
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/a/", "classpath:/b/")
.setCacheControl(CacheControl.maxAge(1180, TimeUnit.SECONDS));
}
};
}
}
5. 路径匹配
5.1 Ant风格路径用法
Ant 风格的路径模式语法具有以下规则:
- *:表示任意数量的字符。
- ?:表示任意一个字符。
- **:表示任意数量的目录。
- {}:表示一个命名的模式占位符。
- []:表示字符集合,例如[a-z]表示小写字母。
例如:
- *.html 匹配任意名称,扩展名为.html的文件。
- /folder1/*/*.java 匹配在folder1目录下的任意两级目录下的.java文件。
- /folder2/**/*.jsp 匹配在folder2目录下任意目录深度的.jsp文件。
- /{type}/{id}.html 匹配任意文件名为{id}.html,在任意命名的{type}目录下的文件。
注意:Ant 风格的路径模式语法中的特殊字符需要转义,如:
- 要匹配文件路径中的星号,则需要转义为\\*。
- 要匹配文件路径中的问号,则需要转义为\\?。
5.2 模式切换
- 如果路径中间需要有 **,替换成ant风格路径
- @PathVariable 用于将 URI 模板中的变量部分绑定到方法的参数上。
- @Slf4j 通过使用 @Slf4j 注解,开发者可以直接在类中使用
log
对象进行日志记录,而无需手动创建和初始化日志对象。
使用ant_path_matcher路径风格:
package org.example.boot.controller;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class MyController {
@GetMapping("/a*/b?/{p1:[a-f]+}") // p1是一个占位符
public String hello(HttpServletRequest req, @PathVariable String path){
log.info("路径变量p1:{}", path);
String url = req.getRequestURI();
return url;
}
}
更改配置文件:
# 改变路径匹配策略:
# ant_path_matcher 老版策略;
# path_pattern_parser 新版策略;
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
6. 内容协商
6.1 默认规则
SpringBoot 多端内容适配
- 基于请求头内容协商:(默认开启)
- 客户端向服务端发送请求,携带HTTP标准的Accept请求头。
- Accept:
application/json
、text/xml
、text/yaml
- 服务端根据客户端请求头期望的数据类型进行动态返回
- Accept:
- 客户端向服务端发送请求,携带HTTP标准的Accept请求头。
- 基于请求参数内容协商:(需要开启)
- 发送请求 GET /projects/spring-boot?format=json
匹配到 @GetMapping("/projects/spring-boot")
根据参数协商,优先返回 json 类型数据【需要开启参数匹配设置】
发送请求 GET /projects/spring-boot?format=xml,优先返回 xml 类型数据
6.2 效果演示
场景:请求同一个接口,可以返回 json 和 xml 不同格式数据。
com.fasterxml.jackson.dataformat
提供了一种方式来以不同的数据格式(如 JSON、XML、YAML 等)读取和写入数据。@JacksonXmlRootElement
用于指定一个 Java 类作为 XML 的根元素@ConfigurationProperties
声明组件的属性和配置文件哪些前缀开始项进行绑定。@NoArgsConstructor
注解后,Lombok 会自动为被注解的类生成一个默认的无参构造函数。@AllArgsConstructor
是Lombok提供的一个注解,用于自动生成包含所有非静态字段的构造函数。@Data
可以帮助我们自动添加类中的一些通用方法,如toString()
、equals()
、hashCode()
和所有字段的getter
和setter
方法。
package org.example.boot.bean;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Data;
@JacksonXmlRootElement // 用于指定一个作为XML的根元素
@Data
public class Person{
private Long id;
private String username;
private String email;
private Integer age;
}
package org.example.boot.controller;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.example.boot.bean.Person;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class MyController {
@GetMapping("/a*/b?/{p1:[a-f]+}")
public String hello(HttpServletRequest req, @PathVariable("p1") String path){
log.info("路径变量p1:{}", path);
String url = req.getRequestURI();
return url;
}
/*
请求同一个接口,可以返回 json 和 xml 不同格式数据。
*/
@GetMapping("/Person")
public Person person(){
Person person = new Person();
person.setId(1L);
person.setAge(25);
person.setUsername("zhangsan");
person.setEmail("aaa@qq.com");
return person;
}
}
# 开启基于请求参数的内容协商功能。 默认参数名:format。 默认此功能不开启
spring.mvc.contentnegotiation.favor-parameter=true
# 指定内容协商时使用的"参数名"。默认是 format
spring.mvc.contentnegotiation.parameter-name=type
默认效果:
开启内容协商:
补充:
Servlet,SpringMVC视频推荐:53_尚硅谷_servlet3.0-简介&测试_哔哩哔哩_bilibili
- HttpServlet 是Java Servlet API 的一个抽象类,用于处理来自客户端的HTTP请求并生成HTTP响应。开发人员可以通过继承HttpServlet类并重写其中的doGet()、doPost()等方法来处理特定的HTTP请求。
- @WebServlet 是Java Servlet规范中的注解,用于标识一个Servlet类,并指定该Servlet处理的URL模式等配置信息。
- @ServletComponentScan 是Spring Boot提供的注解,用于扫描并注册使用@WebServlet、@WebFilter和@WebListener注解标记的Servlet、Filter和Listener类。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="hello">hello</a>
</body>
</html>
package org.example.springmvc.servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import java.io.IOException;
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello....");
}
}