1. 背景
SpringBoot默认配置好了SpringMVC的所有常用特性。如果我们需要全面接管SpringMVC的所有配置并禁用默认配置,仅需要编写一个WebMvcConfigurer配置类定义MVC的底层行为,并标注@EnableWebMvc禁用默认配置即可
2. WebMvcAutoConfiguration自动配置的规则
WebMvcAutoConfiguration是web场景自动配置类,给我们配置了如下所有默认行为:
- 支持Restful的filter:HiddenHttpMethodFilter
- 支持非POST请求,请求体携带数据:FormContentFilter
- WebMvcAutoConfigurationAdapter配置生效,它是一个WebMvcConfigurer,定义MVC默认底层组件
......省略部分......
@Configuration(
proxyBeanMethods = false
)
@Import({EnableWebMvcConfiguration.class})
@EnableConfigurationProperties({WebMvcProperties.class, WebProperties.class})
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
......省略部分......
}
......省略部分......
3.1. WebMvcConfigurer功能
提供方法 | 核心参数 | 功能 | 默认 |
---|---|---|---|
addFormatters | FormatterRegistry | 格式化器:支持属性上@NumberFormat和@DatetimeFormat的数据类型转换 | GenericConversionService |
getValidator | 无 | 数据校验:校验Controller上使用@Valid标注的参数合法性。需要导入starter-validator | 无 |
addInterceptors | InterceptorRegistry | 拦截器:拦截收到的所有请求 | 无 |
configureContentNegotiation | ContentNegotiationConfigurer | 内容协商:支持多种数据格式返回。需要配合支持这种类型的HttpMessageConverter | 支持json |
configureMessageConverters | List<HttpMessageConverter<?>> | 消息转换器:标注@ResponseBody的返回值会利用MessageConverter直接写出去 | 8 个,支持byte、string、multipart、resource、json |
addViewControllers | ViewControllerRegistry | 视图映射:直接将请求路径与物理视图映射。用于无java业务逻辑的直接视图页渲染 | 无<mvc:view-controller> |
configureViewResolvers | ViewResolverRegistry | 视图解析器:逻辑视图转为物理视图 | ViewResolverComposite |
addResourceHandlers | ResourceHandlerRegistry | 静态资源处理:静态资源路径映射、缓存控制 | ResourceHandlerRegistry |
configureDefaultServletHandling | DefaultServletHandlerConfigurer | 默认Servlet:可以覆盖 Tomcat的DefaultServlet。让DispatcherServlet拦截/ | 无 |
configurePathMatch | PathMatchConfigurer | 路径匹配:自定义URL路径匹配。可以自动为所有路径加上指定前缀,比如/api | 无 |
configureAsyncSupport | AsyncSupportConfigurer | 异步支持: | TaskExecutionAutoConfiguration |
addCorsMappings | CorsRegistry | 跨域: | 无 |
addArgumentResolvers | List<HandlerMethodArgumentResolver> | 参数解析器: | mvc默认提供 |
addReturnValueHandlers | List<HandlerMethodReturnValueHandler> | 返回值解析器: | mvc默认提供 |
configureHandlerExceptionResolvers | List<HandlerExceptionResolver> | 异常处理器: | 默认3个。ExceptionHandlerExceptionResolver、ResponseStatusExceptionResolver、DefaultHandlerExceptionResolver |
getMessageCodesResolver | 无 | 消息码解析器:国际化使用 | 无 |
3.2. 视图解析器:InternalResourceViewResolver。配置jsp跳转的路径前缀参数: spring.mvc.view.prefix
3.3. 视图解析器:BeanNameViewResolver。使用示例如下:
package com.hh.springboot3test.config;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.AbstractView;
import java.util.Map;
// 之前在Contoller通过return "viewName"跳转到真实视图: /viewName.html
// 现在在Contoller直接通过return "myBeanView", 跳转到该视图解析器
@Component("myBeanView")
public class MyBeanView extends AbstractView {
// 进行视图渲染
@Override
protected void renderMergedOutputModel(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 这里只是简单的向页面输入内容
response.getWriter().write("myBeanView"); // web页面显示myBeanView
}
}
3.4. 内容协商解析器:ContentNegotiatingViewResolver
3.5. 请求上下文过滤器:RequestContextFilter: 任意位置直接获取当前请求。使用示例:
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// 任意位置随时通过RequestContextHolder获取到当前请求和响应的信息
HttpServletRequest request = attributes.getRequest();
HttpServletResponse response = attributes.getResponse();
String requestURI = request.getRequestURI();
// 访问http://localhost:8080/welcome。这里打印: requestURI: /welcome
System.out.println("requestURI: " + requestURI);
3.6. 静态资源链规则
3.7. ProblemDetailsExceptionHandler:错误详情。SpringMVC内部场景异常被它捕获
- WebMvcAutoConfigurationAdapter导入了EnableWebMvcConfiguration
4.1. RequestMappingHandlerAdapter
4.2. WelcomePageHandlerMapping: 欢迎页功能支持(模板引擎目录、静态资源目录放index.html),项目访问/url根目录就默认展示这个页面
4.3. RequestMappingHandlerMapping:找每个请求由谁处理的映射关系
4.4. ExceptionHandlerExceptionResolver:默认的异常解析器
4.5. LocaleResolver:国际化解析器
4.6. ThemeResolver:主题解析器
4.7. FlashMapManager:临时数据共享
4.8. FormattingConversionService: 数据格式化 、类型转化
application.properties配置参数示例:
# 默认是: dd/MM/yyyy。这样只能解析在application.properties定义的属性: 22/07/2023
spring.mvc.format.date=dd/MM/yyyy
# 默认是: HH:mm:ss
spring.mvc.format.time=HH:mm:ss
4.9. Validator: 数据校验JSR303提供的数据校验功能
4.10. WebBindingInitializer:请求参数的封装与绑定
4.11. ContentNegotiationManager:内容协商管理器
3. @EnableWebMvc禁用默认行为
- @EnableWebMvc给容器中导入DelegatingWebMvcConfiguration组件,它是WebMvcConfigurationSupport
- WebMvcAutoConfiguration有一个核心的条件注解, @ConditionalOnMissingBean(WebMvcConfigurationSupport.class),容器中没有WebMvcConfigurationSupport,WebMvcAutoConfiguration才生效.
- @EnableWebMvc导入WebMvcConfigurationSupport导致 WebMvcAutoConfiguration失效。导致禁用了默认行为
4. 两种模式
1、前后分离模式: @RestController响应JSON数据
2、前后不分离模式:@Controller + Thymeleaf模板引擎