SpringBoot整合SpringMVC

SpringBoot 与 SpringMVC 的关系

SptingBoot需要手动创建XML配置文件 ,并需要手动配置一堆核心组件

而Spring Boot 自动集成了 Spring MVC,提供了默认配置和简化开发的方式:

  • 无需传统 Spring MVC 的 XML 配置
  • 自动配置 中央转发器(DispatcherServlet)、控制器、视图解析器、静态资源访问、消息转换器、格式化、静态资源管理
  • 内嵌 Tomcat/Jetty 等 Web 服务器

引入SpringBoot提供web依赖(spring-boot-starter-web),该依赖中已配置好SpringMVC相关的核心组件。

XML 复制代码
<!--加载web-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

中央转发器 - DispatcherServlet

DispatcherServlet 核心作用

DispatcherServlet是SpringMVC的前端控制器,负责请求的同一分发和处理:

bash 复制代码
客户端请求 → 
前端控制器DispatcherServlet → 
处理映射器HandlerMapping → 
控制器Controller → 
视图解析器ViewResolver → 
响应

传统 SpringMVC 手动配置

传统的SpringMVC必须需要手动在web.xml配置前端控制器DispatcherServlet(可配置多个DispatcherServlet),加载springmvc.xml配置文件,并指定映射路径和启动顺序加载,否则请求进不来。

XML 复制代码
<!-- 1. 前端控制器DispatcherServlet -->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--初始化参数,加载springmvc.xml配置文件-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--启动顺序加载-->
    <load-on-startup>1</load-on-startup>
</servlet>

<!-- 2. Servlet 映射 -->
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
     <!-- URL 映射规则 -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

SpringBoot 自动配置

SpringBoot通过 spring-boot-starter-web 自动配置DispatcherServlet。

不再需要我们在web.xml中配置,我们现在的项目也不是web项目,也不存在web.xml。

注意:只有当用户没有手动注册 DispatcherServletRegistrationBean 时,才启用这个自动配置。

配置流程时序图

bash 复制代码
启动流程:
1. SpringApplication.run()
   ↓
2. 加载自动配置类
   ↓
3. DispatcherServletAutoConfiguration
   │
   ├── @Conditional 检查
   │   └── 用户是否手动注册了 DispatcherServletRegistrationBean?
   │       ├── 是:跳过此配置
   │       └── 否:继续
   │
   ├── @Import(DispatcherServletConfiguration.class)
   │   └── 创建 DispatcherServlet bean
   │       └── 设置属性:dispatchOptionsRequest 等
   │
   └── DispatcherServletRegistrationConfiguration
       └── 创建 DispatcherServletRegistrationBean
           ├── 设置 URL 映射:spring.mvc.servlet.path
           ├── 设置启动顺序:spring.mvc.servlet.load-on-startup
           └── 设置 Multipart 配置(如果存在)
   ↓
4. 注册到 Servlet 容器

自定义:在SpringBoot中手动配置

bash 复制代码
# application.yml 中的默认配置
spring:
  mvc:
    servlet:
      # DispatcherServlet 的映射路径,默认为 "/"
      path: /
      # 启动顺序,默认为 -1(延迟加载)
      load-on-startup: -1
    
    # 其他相关配置
    throw-exception-if-no-handler-found: false
    static-path-pattern: /**
    
server:
  servlet:
    # Servlet 上下文路径
    context-path: /app

Spring Boot vs 传统 Spring MVC 对比

特性 传统 Spring MVC Spring Boot
配置方式 XML 或 Java Config 自动配置 + 属性文件
DispatcherServlet 注册 web.xml DispatcherServletAutoConfiguration
服务器 外部服务器部署 内嵌服务器
启动流程 复杂,需配置 web.xml 简单,main 方法启动
默认配置 需要手动配置所有组件 提供合理默认值

控制器 - Controller

Controller 基础概念

Controller是MVC架构中的控制器层,负责:

  1. 接收HTTP请求
  2. 调用业务逻辑层
  3. 返回响应(视图或数据)

传统 SpringMVC 手动配置

SpringMVC需要手动配置控制器,才能正常工作:

  1. 在web.xml配置文件中 指定 Spring MVC 配置文件位置

  2. 在springmvc.xml配置文件中 启动组件扫描

    XML 复制代码
    <!-- 开启mvc注解驱动 -->
    <mvc:annotation-driven/>
    
    <!-- 配置spring创建容器时要扫描的包 -->
    <context:component-scan base-package="com.qcby.controller"></context:component-scan>
  3. 在 Controller 类中添加**@Controller 注解**

SpringBoot 自动配置

Spring Boot 通过 spring-boot-starter-web 自动配置 Controller 支持。

  1. 直接在Controller 类中添加**@Controller/@RestController 注解**即可。
  2. 不需要配置文件,在启动类 中的 @SpringBootApplication 注解中包含自动扫描 @Controller/@RestController 的注解类。

Controller自动配置的核心类

启动流程时序图

bash 复制代码
// Spring Boot 启动流程
1. SpringApplication.run(Application.class, args)
   ↓
2. 创建 AnnotationConfigApplicationContext
   ↓
3. 注册主配置类(被 @SpringBootApplication 标记的类)
   ↓
4. 解析 @ComponentScan
   ├── 扫描主类所在包及其子包
   ├── 注册所有 @Component、@Service、@Repository、@Controller 等
   └── 应用 excludeFilters
   ↓
5. 解析 @EnableAutoConfiguration
   ├── 加载 spring.factories 中的自动配置类
   ├── 应用条件注解(@ConditionalOnClass 等)
   └── 注册符合条件的配置类
   ↓
6. 刷新应用上下文
   ├── 实例化单例 bean
   ├── 执行初始化方法
   └── 发布应用启动事件

自定义:在SpringBoot中手动配置

在启动类下添加 @ComponentScan 指定扫描路径:

java 复制代码
@SpringBootApplication
@ComponentScan("com.xxx") // 扫描com.xxx下所有组件
public class SpringBootThymeleaf {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootThymeleaf.class,args);
    }
}

Spring Boot vs Spring MVC Controller 对比

特性 传统 Spring MVC Spring Boot
配置方式 XML 或 Java Config 手动配置 自动配置 + 属性文件
启动方式 部署到外部 Servlet 容器 内嵌服务器,main 方法启动
依赖管理 手动管理依赖版本 starter 自动管理
默认配置 需要手动配置所有组件 提供合理的默认值
包扫描 需要显式配置 @ComponentScan 自动从主类开始扫描

视图解析器 - View Resolver

View Resolver 的作用

bash 复制代码
HTTP请求 → 
DispatcherServlet → 
Controller → 
返回视图名称 → 
ViewResolver → 
定位视图 → 
渲染视图 → 
响应

传统 SpringMVC 手动配置

在springmvc.xml配置文件中配置 JSP 相关的视图解析器 InternalResourceViewResolver ,指定页面的前缀和后缀

XML 复制代码
<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--页面前缀-->
    <property name="prefix" value="/WEB-INF/views/"></property>
    <!--页面后缀-->
    <property name="suffix" value=".jsp"></property>
</bean>

SpringBoot 自动配置

SpringBoot自动配置了两个核心视图解析器:

  • **ContentNegotiatingViewResolver(内容协商视图解析器):**遍历所有的视图解析器,选择最佳的视图。

  • **BeanNameViewResolver(Bean名称视图解析器):**在 ApplicationContext 中查找指定名称的 View Bean

  • 两种视图解析器的对比

    | 特性 | ContentNegotiatingViewResolver | BeanNameViewResolver |
    | 主要用途 | 内容协商,支持多种响应格式 | 通过Bean名称查找视图 |
    | 工作方式 | 协调多个视图解析器 | 直接查找View Bean |
    | 配置复杂度 | 较高,需要配置媒体类型映射 | 简单,只需定义View Bean |
    | 灵活性 | 高,支持动态格式选择 | 中等,需要预定义View |
    | 性能 | 较低,需要遍历解析器 | 较高,直接获取Bean |

    适用场景 REST API,多格式输出 报表导出,特殊视图

源码:

自定义:在SpringBoot中手动配置

bash 复制代码
# application.yml 配置
# 通用视图配置
spring:
  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp
  
  # Thymeleaf 配置
  thymeleaf:
    prefix: classpath:/templates/
    suffix: .html
    encoding: UTF-8

文件上传 - MultipartResolver

处理前端发来的文件上传请求(enctype="multipart/form-data),把上传的文件解析成 MultipartFile对象。

html 复制代码
# 文件上传请求
<form action="/upload" method="post" enctype="multipart/form-data">
    <input name="pic" type="file">
    <input type="submit">
</form>

传统 SpringMVC 手动配置

  1. 先导入文件上传相关依赖包

    XML 复制代码
    <!--文件上传依赖jar包导入-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>
  2. 在springmvc.xml配置文件中配置文件上传解析器组件,并指定文件上传大小

    XML 复制代码
    <!--配置文件上传的解析器组件,id名称是固定的,不能更改-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--设置上传文件总大小 8M=8*1024*1024-->
        <property name="maxUploadSize" value="8388608"></property>
    </bean>

SpringBoot 自动配置

SpringBoot自动配置MultipartAutoConfiguration,临时存储位置、上传大小等都自动配置:

自定义:在SpringBoot中手动配置

bash 复制代码
# application.yml 配置
# 文件上传配置
spring:
  servlet:
    multipart:
      enabled: true                     # 启用文件上传
      location: /tmp/uploads           # 临时文件目录
      file-size-threshold: 0           # 文件大小阈值(0=总是写入磁盘)
      max-file-size: 10MB              # 单个文件最大大小
      max-request-size: 100MB          # 请求整体最大大小
      resolve-lazily: false            # 是否延迟解析

静态资源访问

SpringMVC 默认会拦截所有请求,需要专门配置让它放行静态资源。

传统 SpringMVC 手动配置

在springmvc.xml文件中配置**<mvc:resources>**,指定静态资源的路径和映射:

XML 复制代码
<!-- 放行static下的所有静态资源 -->
<mvc:resources mapping="/**" location="/static/"/>

SpringBoot 自动配置

导入webjar依赖:

XML 复制代码
<!--引入jquery‐webjar 在访问的时候只需要写webjars下面资源的名称即可-->
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1</version>
</dependency>

设置了4个静态资源目录,"/**" 访问当前项目的任何资源,都去(静态资源的文件夹)找映射、

bash 复制代码
"classpath:/META‐INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"

Spring MVC vs Spring Boot 配置对比

特性 Spring MVC Spring Boot
配置方式 XML 或 Java Config 属性文件 + 自动配置
默认实现 需要手动选择 StandardServletMultipartResolver
配置位置 web.xml + springmvc.xml application.yml
依赖管理 手动添加依赖 starter 自动管理

消息转换 - HttpMessageConverter

HttpMessageConverter核心场景

  • 前端发送请求,读取请求体 转成 Java 对象(比如 @RequestBody 接收参数)
  • 后端返回 Java 对象,把 Java 对象写入 响应体 给前端(比如 @ResponseBody 注解)

传统 SpringMVC 手动配置

在springmvc.xml文件中配置消息转换器 <mvc:message-converters>

XML 复制代码
<!-- spring-mvc.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="...">
    
    <!-- 启用注解驱动,包含默认消息转换器 -->
    <mvc:annotation-driven>
        <!-- 配置消息转换器 -->
        <mvc:message-converters>
            <!-- 字符串转换器,设置编码 -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            
            <!-- JSON 转换器(Jackson) -->
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                        <value>application/*+json;charset=UTF-8</value>
                    </list>
                </property>
                <property name="objectMapper" ref="objectMapper"/>
            </bean>
            
            <!-- XML 转换器(JAXB) -->
            <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/xml;charset=UTF-8</value>
                        <value>text/xml;charset=UTF-8</value>
                    </list>
                </property>
            </bean>

            <!-- 日期类型 转换器 -->
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>
                <property name="features">
                    <array>
                        <value>WriteMapNullValue</value>
                        <value>WriteNullStringAsEmpty</value>
                    </array>

                </property>
                <property name="dateFormat" value="yyyy-MM-dd"></property>
            </bean>
            
            <!-- Form 表单转换器 -->
            <bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>
</beans>

SpringBoot 自动配置

Springboot自动配置了消息转换器

自定义

bash 复制代码
# application.yml 配置
# Jackson 配置
spring:
  jackson:
    # 日期格式化
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    locale: zh_CN
    
    # 序列化配置
    serialization:
      write-dates-as-timestamps: false  # 日期不写为时间戳
      write-date-timestamps-as-nanoseconds: false
      write-durations-as-timestamps: false
      indent-output: true               # 格式化输出
      fail-on-empty-beans: false
      write-self-references-as-null: true
    
    # 反序列化配置
    deserialization:
      fail-on-unknown-properties: false  # 忽略未知属性
      fail-on-ignored-properties: false
      fail-on-invalid-subtype: false
      unwrap-root-value: false
    

# HTTP 编码配置
server:
  servlet:
    encoding:
      charset: UTF-8
      enabled: true
      force: true
      force-request: true
      force-response: true

格式化 - Formatter

基础数据转换器,处理简单数据类型的转换 ,比如:
**时间格式化:**字符串转日期(前端传 "2024-01-01",后端用 Date/LocalDateTime 接收)。

传统 SpringMVC 手动配置

在springmvc.xml文件中配置格式化:

XML 复制代码
<!-- 启用注解驱动,包含格式化支持 -->
<mvc:annotation-driven conversion-service="conversionService"/>
    
<!-- 配置格式化服务 -->
<bean id="conversionService" 
          class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
     <!-- 注册格式化器 -->
    <property name="formatters">
        <set>
            <!-- 日期格式化器 -->
            <bean class="org.springframework.format.datetime.DateFormatter">
                <constructor-arg value="yyyy-MM-dd"/>
            </bean>
        </set>
    </property>
</bean>

SpringBoot 自动配置

格式化转换器的自动注册

bash 复制代码
# application.yml 格式化配置
spring:
  mvc:
    format:
      # 日期格式化  只影响表单参数绑定(POST/PUT请求)
      date: yyyy-MM-dd
      date-time: yyyy-MM-dd HH:mm:ss
      time: HH:mm:ss

  # Jackson 配置下的日期格式化  只影响JSON响应(@ResponseBody)
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    locale: zh_CN

Thymeleaf模板引擎中的日期格式化,使用 #dates 工具对象

html 复制代码
<!--使用thymeleaf模板输出,且使用 #dates 工具对象-->
<div th:text="${#dates.format(person.birth,'yyyy-MM-dd')}"></div>
相关推荐
千寻技术帮2 小时前
10386_基于SpringBoot的外卖点餐管理系统
java·spring boot·vue·外卖点餐
曹轲恒2 小时前
SpringBoot整合SpringMVC(末)
java·spring boot·后端
_周游2 小时前
Java8 API 文档搜索引擎_2.索引模块(程序)
java·搜索引擎·intellij-idea
小马爱打代码2 小时前
Spring Boot:邮件发送生产可落地方案
java·spring boot·后端
BD_Marathon2 小时前
设计模式——接口隔离原则
java·设计模式·接口隔离原则
树码小子2 小时前
SpringMVC(10)综合案例练习:计算器,登录
spring·mvc
空空kkk2 小时前
SSM项目练习——hami音乐(二)
java
闻哥2 小时前
深入理解 ES 词库与 Lucene 倒排索引底层实现
java·大数据·jvm·elasticsearch·面试·springboot·lucene
2 小时前
java关于引用
java·开发语言