SpringBoot 第二课(Ⅰ) 整合springmvc(详解)
目录
一、SpringBoot对静态资源的映射规则
1. WebJars 资源访问
2. 静态资源访问
3. 欢迎页配置
二、SpringBoot整合springmvc
概述
Spring MVC组件的自动配置
中央转发器(DispatcherServlet)
控制器(Controller)
视图解析器
实现springmvc的文件上传
upload.html
FileUploadController.java(/upload)
消息转换和格式化
1.消息转换器
概念
2.格式化
①实现WebMvcConfigurer接口
②配置文件编写
三、Springboot扩展springmvc
1.在容器中注册视图控制器(请求转发)
2.拦截器设置
补充(配置类的加载顺序)
经过前面对SpringBoot第一课的学习,大致也总结出对springboot的使用流程:
①创建 Spring Boot 应用并选择模块(参见下面博客):SpringBoot(一)--搭建架构5种方法_springboot框架搭建-CSDN博客文章浏览阅读2.2k次,点赞19次,收藏39次。Spring Boot 是基于 Spring 框架,以约定优于配置、自动配置为核心,可快速构建独立运行的应用,为微服务等开发提供便利的开发框架。前面已经对SSM(Spring,SpringMVC,MyBatis)每个框架做了讲解,SpringBoot就是基于这个框架一个更简单、更有利于开发。_springboot框架搭建
https://blog.csdn.net/m0_74977981/article/details/146139845?spm=1001.2014.3001.5501
②少量配置即可运行:Spring Boot 具有自动配置的特性,默认将很多常见的开发场景(如 Web 开发的服务器配置、数据库连接的基础配置等)都配置好了。开发者不需要进行大量复杂的配置工作,只需要在配置文件(如 application.properties 或 application.yml)中指定少量必要的配置信息,就能够让应用程序运行起来。
③编写业务代码:当 Spring Boot 应用创建好并且基本配置完成后,开发者就可以专注于编写具体的业务逻辑代码了。例如,实现用户登录、数据处理、业务规则判断等功能,来满足实际项目的需求。
本文章就解读“少量配置”和“编写业务代码”两方面进行讲解。
在开始讲解之前,先来说一说Spring Boot 框架中的两个核心概念:自动配置(AutoConfiguration)和属性配置(Properties)
-
xxxxAutoConfiguration(给容器中自动配置组件):指的是自动配置类,这些类帮助我们在 Spring Boot 应用中自动配置各种组件。Spring Boot 通过这些自动配置类,根据类路径中的 jar 包依赖和配置文件中的设置,自动配置应用的各个部分,从而简化了配置过程。
-
xxxxProperties(配置类来封装配置文件中的内容):指的是配置属性类,这些类用于封装外部配置文件(如
application.properties
或application.yml
)中的内容。通过将配置文件中的属性映射到这些类中的字段,Spring Boot 能够将配置值注入到应用的各个组件中,实现配置的集中管理和使用。
所以向查看这两个方面的源码,可以参见类名带这两个后缀的类。
一、SpringBoot对静态资源的映射规则
在 Spring Boot 2.4 之前,静态资源的配置属性主要由 ResourceProperties
类来管理,它位于 org.springframework.boot.autoconfigure.web
包下,相关配置项以 spring.resources
作为前缀;
但是在从 Spring Boot 2.4 开始,静态资源的配置属性被整合到了 WebProperties
类中,该类位于 org.springframework.boot.autoconfigure.web
包下。其中,静态资源相关的配置被封装在 WebProperties.Resources
这个内部类里(WebProperties的前缀是spring.web,而ResourceProperties
作为内部封装类,它的前缀依旧是 spring.resources
,所以2.4后想在配置文件更改它的信息前缀就变成了spring.web.resources
)。
可以在External Libraries里查看(由于我用的是2.7.0版本,所以在这里我就展示WebProperties类,代码功能都是一样的
):

就在这个包里面,顺着org.springframework.boot.autoconfigure.web查看
:

可以点开查看这个封装类的源码:

可以看见内部:

1. WebJars 资源访问
WebJars 是一种将前端库(如 jQuery、Bootstrap 等)打包成 Java 可识别的 JAR 文件的方式。这样做的好处是可以利用 Maven 或 Gradle 等构建工具来管理这些库的依赖,同时保持项目的依赖关系清晰。
在 Spring Boot 项目中,所有以 /webjars/**
开头的请求都会被映射到 classpath:/META-INF/resources/webjars/
目录下寻找资源。这意味着,如果在项目中引入了 WebJars 资源,你可以通过 /webjars/
路径前缀来访问这些资源。
【注:所有以
/webjars/**
开头的请求通常是指那些通过<groupId>org.webjars</groupId>
引入的依赖】
例如,如果在 pom.xml
文件中添加了以下依赖:
<dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.3.1</version>
</dependency>
那么就可以通过访问 http://localhost:8080/webjars/jquery/3.3.1/jquery.js
来获取 jQuery 库的 JavaScript 文件。
也可以在External Libraries这里查看:

2. 静态资源访问
在 Spring Boot 项目中,可以通过多种路径前缀来访问静态资源。这些路径前缀包括(优先级也是下面这个顺序从高到低):
-
classpath:/META-INF/resources/
-
classpath:/resources/
-
classpath:/static/
-
classpath:/public/
在 Maven 项目中,这些目录可能位于:
src/main/resources/META-INF/resources/
src/main/resources/resources/
src/main/resources/static/
src/main/resources/public/
这些路径通常对应于项目中的目录结构,例如 Maven 项目中的 src/main/resources
目录。通过这些路径,可以访问存放在这些目录下的静态资源,如 HTML、CSS、JavaScript 文件等。
例如,如果在 src/main/resources/static
目录下有一个名为 abc
的文件,可以通过访问 http://localhost:8080/abc
来获取这个文件。
3. 欢迎页配置
在 Spring Boot 项目中,可以通过配置来设置欢迎页。当用户访问应用的根路径(如 http://localhost:8080/
)时,Spring Boot 会尝试在静态资源文件夹下查找 index.html
文件作为欢迎页。
如果在静态资源文件夹下存在多个 index.html
文件,Spring Boot 会按照一定的规则选择一个作为欢迎页。通常,它会查找第一个找到的 index.html
文件。
这种方式使得配置欢迎页变得非常简单,只需要在静态资源文件夹下放置一个 index.html
文件即可。

二、SpringBoot整合springmvc
springboot整合mvc本质来说就是对它的组件实现了自动装配:
中央转发器(DispatcherServlet)
控制器
视图解析器
静态资源访问
消息转换器
格式化
静态资源管理
这些组件在springmvc中的运作流程和功能详见下面这篇博客:
SpringMVC(二)原理_springmvc和maven-CSDN博客文章浏览阅读1.2k次,点赞27次,收藏13次。1. 当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象,就会加载springmvc.xml配置文件。前缀是/html/,后缀是.html,所以return时,返回的其实是,/html/suc.html,即一个前端界面。7.点击重写,选择D:盘apache-maven下conf下的logging下的setting.xml,点击确定。4. 根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件。_springmvc和maven
https://blog.csdn.net/m0_74977981/article/details/144885878?spm=1001.2014.3001.5501(内置有图解)
概述
Spring Boot对Spring MVC进行了自动配置,简化了Spring MVC的使用。它通过自动配置类(如WebMvcAutoConfiguration
)和注解扫描,使得开发者无需手动配置大量的Spring MVC相关组件,如DispatcherServlet
、视图解析器、消息转换器等。同时,Spring Boot还提供了扩展机制,允许开发者根据业务需求进行自定义配置。
Spring MVC组件的自动配置
中央转发器(DispatcherServlet)
-
自动配置:Spring Boot自动接管了
DispatcherServlet
的配置,无需在web.xml
中手动配置。DispatcherServlet
的配置由DispatcherServletAutoConfiguration
类完成。 -
默认配置:默认情况下,
DispatcherServlet
拦截/
路径下的所有请求(包括静态资源,但不包括JSP请求)。可以通过server.servletPath
属性修改其拦截路径。
控制器(Controller)
-
自动管理:在Spring Boot的注解扫描范围内,使用
@Controller
或@RestController
注解的类会被自动识别并管理为Spring MVC的控制器。 -
注解扫描:Spring Boot默认会扫描与主应用类同级或子级的包中的注解类。如果需要扫描其他包,可以通过
@ComponentScan
注解指定。
视图解析器
-
自动配置:Spring Boot自动配置了视图解析器,包括
InternalResourceViewResolver
和ContentNegotiatingViewResolver
等。 -
默认配置:默认的视图解析器前缀为
classpath:/templates/
,后缀为.html
(如果使用Thymeleaf模板引擎的话-引入了Thymeleaf的依赖)。可以通过application.properties
文件中的spring.mvc.view.prefix
和spring.mvc.view.suffix
属性进行自定义(这个出自于WebMvcProperties封装类)。
实现springmvc的文件上传
当我们做文件上传的时候我们也会发现multipartResolver是自动被配置好的,它被封装在MultipartAutoConfiguration类中,处 org.springframework.boot.autoconfigure.web.servlet
包下。

可以通过配置文件配置如下属性:
# 是否启用文件上传支持,默认为 true
spring.servlet.multipart.enabled=true# 上传文件的临时存储目录
spring.servlet.multipart.location=# 单个文件的最大大小,默认为 1MB
spring.servlet.multipart.max-file-size=1MB# 整个请求的最大大小,默认为 10MB
spring.servlet.multipart.max-request-size=10MB# 文件写入磁盘的阈值,默认值为 0
spring.servlet.multipart.file-size-threshold=0# 是否延迟解析多部分请求,默认为 false
spring.servlet.multipart.resolve-lazily=false
在讲解示例之前,照例展示我用的pom.xml文件:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.qcby</groupId><artifactId>springboot2</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot2</name><description>springboot2</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.3.1</version></dependency><!--热部署--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><!--thymeleaf模块支撑--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--消息转换扩展--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

upload.html
<!DOCTYPE html>
<html lang="en">
<head><title>File Upload</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data"><input name="pic" type="file"><input type="submit">
</form>
</body>
</html><!--
action 属性:指定表单数据提交的目标 URL。在这段代码中,action="/upload" 表示表单数据将被发送到服务器的 /upload 路径进行处理。
method 属性:规定表单数据的提交方式,常见的有 GET 和 POST。这里使用 method="post",意味着表单数据会以 HTTP POST 请求的方式发送到服务器,适合用于提交包含敏感信息或大量数据的表单,如文件上传。
enctype 属性:指定表单数据在发送到服务器之前的编码方式。对于文件上传,必须使用 enctype="multipart/form-data",这种编码方式允许表单数据以多部分的形式进行传输,能够处理二进制文件数据。
-->
FileUploadController.java(/upload)
package com.qcby.springboot2;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import java.io.*;@Controller //标记为一个控制器类
public class FileUploadController {@ResponseBody@RequestMapping(value = "/upload", method = RequestMethod.POST)public String upload(@RequestParam("pic") MultipartFile file, HttpServletRequest request) {//@RequestParam("pic") MultipartFile file:从请求中获取名为 pic 的文件参数(在html表单中设置了),MultipartFile 是 Spring 框架提供的用于处理文件上传的接口。String contentType = file.getContentType();String fileName = file.getOriginalFilename();String filePath = "D:\\001_Myclass001\\javava\\TestAll"; // 修改路径try {this.uploadFile(file.getBytes(), filePath, fileName);} catch (Exception e) {// TODO: handle exceptionreturn "upload error";}return "upload"; //上传成功后在前端返回字符串}public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {File targetFile = new File(filePath);if (!targetFile.exists()) {targetFile.mkdirs();}FileOutputStream out = new FileOutputStream(filePath + File.separator + fileName); // 使用 File.separatorout.write(file);out.flush();out.close();}
}
启动项目框架,输入“http://localhost:8080/upload”(因为我没有在配置文件中更改路径或端口号):
得到:

选择文件并提交后就可以得到:

消息转换和格式化
1.消息转换器
概念
消息转换器(Message Converters)是 Spring MVC 中的一个核心组件,用于在 HTTP 请求和响应中进行数据的序列化和反序列化,这是前后端交互(交互产生的信息都是消息)过程中不可或缺的一部分。当客户端发送请求时,消息转换器会将请求体中的数据转换为 Java 对象;当服务器返回响应时,消息转换器会将 Java 对象转换为合适的响应体格式(如 JSON、XML 等)。
Springboot自动配置了消息转换器(HttpMessageConvertersAutoConfiguration类中)
2.格式化
格式化通常指的是将数据转换成特定格式的过程,以便它可以用于显示、存储或传输(封装在)。
实现格式化功能可以通过实现WebMvcConfigurer
接口和在配置文件中编写配置这两种方式来实现。
以时间格式化为例:
①实现WebMvcConfigurer
接口
②配置文件编写
实现
WebMvcConfigurer
接口和在配置文件中编写配置这两种有什么区别呢?最大的区别就是通过实现接口的方式配置功能更加自由。
如下是配置文件的几种选项
但是通过实现接口的方式进行配置可以有更多选择。
三、Springboot扩展springmvc
在实际开发中springboot并非完全自动化,很多跟业务相关我们需要自己扩展,springboot给我提供了接口,我们可以来通过实现WebMvcConfigurer接口来扩展。

我为这个源码加上了注释,标明每个方法是可以拓展什么:
package org.springframework.web.servlet.config.annotation;import java.util.List;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;public interface WebMvcConfigurer {// 配置路径匹配的选项default void configurePathMatch(PathMatchConfigurer configurer) {}// 配置内容协商选项(例如,基于请求头的内容类型和接受类型来选择响应的媒体类型)default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}// 配置异步请求处理(例如,使用DeferredResult或Callable来处理长时间运行的任务)default void configureAsyncSupport(AsyncSupportConfigurer configurer) {}// 配置默认的Servlet处理(例如,映射到dispatcherServlet的URL路径)default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}// 添加自定义格式化器到FormatterRegistry,用于数据绑定时的格式化和解析default void addFormatters(FormatterRegistry registry) {}// 添加拦截器到拦截器注册表,用于拦截和处理请求default void addInterceptors(InterceptorRegistry registry) {}// 添加资源处理器到资源处理器注册表,用于处理静态资源请求default void addResourceHandlers(ResourceHandlerRegistry registry) {}// 添加跨域资源共享(CORS)映射到CORS注册表default void addCorsMappings(CorsRegistry registry) {}// 添加视图控制器到视图控制器注册表,用于处理特定的URL路径default void addViewControllers(ViewControllerRegistry registry) {}// 配置视图解析器选项default void configureViewResolvers(ViewResolverRegistry registry) {}// 添加自定义参数解析器到参数解析器列表,用于解析控制器方法的参数default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {}// 添加自定义返回值处理器到返回值处理器列表,用于处理控制器方法的返回值default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {}// 配置消息转换器列表,用于处理HTTP请求和响应的序列化和反序列化default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}// 扩展消息转换器列表,可以添加或修改现有的消息转换器default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}// 配置异常解析器列表,用于解析和处理异常default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}// 扩展异常解析器列表,可以添加或修改现有的异常解析器default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}// 提供一个自定义的验证器(Validator)实例,用于数据验证@Nullabledefault Validator getValidator() {return null;}// 提供一个自定义的消息代码解析器(MessageCodesResolver)实例,用于解析验证错误消息的代码@Nullabledefault MessageCodesResolver getMessageCodesResolver() {return null;}
}
下面就来简单用一下实现接口配置来实现业务:
1.在容器中注册视图控制器(请求转发)
@Controller
public class MyMVCCofnig implements WebMvcConfigurer {@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/tx").setViewName("success");//将 /tx 路径映射到 success 视图下(前端页面)}
2.拦截器设置
拦截类:
package com.qcby.springboot2;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 拦截器*/
@Component
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("前置拦截");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("后置拦截");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("最终拦截");}
}
实现WebMvcConfigurer类的Java:
package com.qcby.springboot2;import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.List;@Controller
public class MyMVCCofnig implements WebMvcConfigurer {/*** 重写拦截器** 配置一个名为MyInterceptor的拦截器,使其应用于所有请求路径,除了/hello2(拦截所有请求,除了hello2)*可以得到结果,在访问hello2时,并不会在控制台打印拦截,但是当访问hello1时(对比),就会打印三条拦截消息* */@Autowiredprivate MyInterceptor myInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor).addPathPatterns("/**").excludePathPatterns("/hello2");}
}
再来一个controller类:
package com.qcby.springboot2;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController1 {@GetMapping("/hello1")public String hello() {return "Hello, World 1!";}@GetMapping("/hello2")public String hello2() {return "Hello, World 2!";}
}
可以得到:

由于除了hello2请求,其他的都会受到拦截,所以这里的hello1请求就会收到后台的拦截类提醒(准确来说访问除hello2外的所有请求都会收到拦截通知):
现在清空后台再来访问一下hello2试验一下:


补充(配置类的加载顺序)
可以注意到在上面展示的那些源码中,经常会有
@AutoConfigureOrder
和@Order这两个注解:
首先@AutoConfigureOrder
和@Order
注解是用于控制Spring Boot配置类的加载顺序的。
@Order 是通用的,适用于所有Spring管理的Bean,控制加载或执行顺序。
@AutoConfigureOrder 是专门用于Spring Boot自动配置类的,确保自动配置类的加载顺序。
序列规则:两者都遵循“值越小,优先级越高”的规则,但默认值不同(
@Order
默认为Integer.MAX_VALUE
,@AutoConfigureOrder
默认为0
)。