Spring MVC配置全解析

以下内容是 Spring Framework 官方文档中关于 MVC 配置(MVC Config) 的详细说明,特别是 1.11 节 "MVC Config" 的完整章节。这一部分内容非常系统地介绍了如何通过 Java 注解配置和 XML 配置来定制 Spring MVC 的行为。

以下是对该文档内容的结构化总结与关键点解析,帮助您更好地理解其用途和应用场景:


🌐 Spring MVC 配置概览

Spring 提供了两种方式来启用和自定义 MVC 行为:

  • Java 配置 :使用 @EnableWebMvc + 实现 WebMvcConfigurer
  • XML 配置 :使用 <mvc:annotation-driven /> 及相关标签

⚠️ 注意:虽然标题中有 "WebFlux",但本节实际描述的是 Spring MVC(基于 Servlet 的阻塞式框架),而非响应式 WebFlux。可能是文档版本混淆所致。


🔧 各配置项详解

1.11.1 ✅ 启用 MVC 配置

  • Java : @EnableWebMvc 注解开启默认 MVC 支持。
  • XML : <mvc:annotation-driven /> 实现相同功能。
  • 功能:自动注册 RequestMappingHandlerMapping, RequestMappingHandlerAdapter, 消息转换器等核心组件。

1.11.2 🛠️ MVC 配置 API

  • 实现 WebMvcConfigurer 接口进行扩展(Java)
  • XML 中通过 <mvc:annotation-driven> 的子标签或属性配置
  • 不需要手动创建底层 Bean,Spring 自动处理

1.11.3 🔢 类型转换(Type Conversion)

  • 默认注册数字、日期格式化器(支持 @NumberFormat, @DateTimeFormat
  • 自定义方式:
    • Java: 重写 addFormatters(FormatterRegistry)
    • XML: 定义 FormattingConversionServiceFactoryBean 并关联到 <mvc:annotation-driven conversion-service="..." />
  • 特别提示:浏览器对 <input type="date"> 使用 ISO 格式,建议设置 DateTimeFormatterRegistrar.setUseIsoFormat(true)

1.11.4 ✅ 校验(Validation)

  • 若类路径存在 Bean Validation(如 Hibernate Validator),自动注册 LocalValidatorFactoryBean
  • 自定义全局校验器:
    • Java: 重写 getValidator()
    • XML: <mvc:annotation-driven validator="globalValidator"/>
  • 局部校验:在 Controller 中使用 @InitBinder 添加特定 Validator

1.11.5 🪝 拦截器(Interceptors)

  • 用于请求预处理/后处理

  • Java:

    java 复制代码
    registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
  • XML:

    xml 复制代码
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/admin/**"/>
            <bean class="com.example.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

1.11.6 📦 内容协商(Content Negotiation)

控制如何根据请求决定返回内容类型(JSON/XML 等)

  • 默认策略:先看 URL 扩展名(.json, .xml),再看 Accept

  • 推荐仅使用 Accept 头,避免路径污染和安全风险(RFD 攻击)

  • Java:

    java 复制代码
    configurer.mediaType("json", MediaType.APPLICATION_JSON);
  • XML:

    xml 复制代码
    <bean class="ContentNegotiationManagerFactoryBean">
        <property name="mediaTypes">
            json=application/json
        </property>
    </bean>

1.11.7 💬 消息转换器(Message Converters)

控制 HTTP 请求/响应体的序列化(如 JSON ↔ 对象)

两种方式:
  • configureMessageConverters()替换默认转换器
  • extendMessageConverters()扩展或修改默认转换器

✅ 推荐使用 extendMessageConverters() 保留默认行为

示例:自定义 Jackson ObjectMapper
java 复制代码
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
        .indentOutput(true)
        .dateFormat(new SimpleDateFormat("yyyy-MM-dd"))
        .modulesToInstall(new ParameterNamesModule());
    converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}

Spring Boot 中更推荐用 Jackson2ObjectMapperBuilder 统一配置。


1.11.8 🖼️ 视图控制器(View Controllers)

快捷方式,将某个 URL 直接映射到视图(无需 Controller 方法)

  • Java:

    java 复制代码
    registry.addViewController("/").setViewName("home");
  • XML:

    xml 复制代码
    <mvc:view-controller path="/" view-name="home"/>

⚠️ 注意:不能与 @RequestMapping 冲突,否则会报 405 错误


1.11.9 🧩 视图解析器(View Resolvers)

简化视图技术的配置,如 JSP、Thymeleaf、FreeMarker、JSON 视图等

  • Java:

    java 复制代码
    registry.enableContentNegotiation(new MappingJackson2JsonView());
    registry.jsp();
  • XML:

    xml 复制代码
    <mvc:view-resolvers>
        <mvc:content-negotiation>
            <mvc:default-views>
                <bean class="MappingJackson2JsonView"/>
            </mvc:default-views>
        </mvc:content-negotiation>
        <mvc:jsp/>
    </mvc:view-resolvers>

若使用 FreeMarker/Tiles 等,还需额外配置模板加载路径(FreeMarkerConfigurer


1.11.10 📁 静态资源处理

配置静态文件(CSS/JS/图片)的访问路径和缓存策略

  • Java:

    java 复制代码
    registry.addResourceHandler("/resources/**")
            .addResourceLocations("/public/", "classpath:/static/")
            .setCachePeriod(31556926); // 1 year
  • XML:

    xml 复制代码
    <mvc:resources mapping="/resources/**" location="/public, classpath:/static/" cache-period="31556926"/>
高级功能:资源链(Resource Chain)

支持版本化 URL(防缓存)、Gzip 压缩等

  • 使用 VersionResourceResolver + ContentVersionStrategy(基于内容哈希)
  • WebJars 支持:自动解析 /jquery/jquery.min.js → /jquery/3.6.0/jquery.min.js

1.11.11 🏠 默认 Servlet 处理

允许将 DispatcherServlet 映射为 /,同时让容器默认 Servlet 处理静态资源

  • Java:

    java 复制代码
    configurer.enable();
  • XML:

    xml 复制代码
    <mvc:default-servlet-handler/>

⚠️ 原理:添加一个最低优先级的 DefaultServletHttpRequestHandler,转发未匹配请求给容器默认 Servlet

如果默认 Servlet 名称非标准(如 Tomcat 的 default),需手动指定名称


1.11.12 🔍 路径匹配(Path Matching)

自定义 URL 匹配规则

常见配置:

java 复制代码
configurer
    .setUseTrailingSlashMatch(false) // 是否匹配尾部斜杠
    .setUseSuffixPatternMatch(true)  // 是否允许 .json/.xml 后缀匹配
    .addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController.class)); // 为所有 @RestController 添加前缀 /api

推荐关闭后缀匹配(.json)以提升安全性(防止 RFD 攻击)


1.11.13 ⚙️ 高级 Java 配置

  • 移除 @EnableWebMvc
  • 直接继承 DelegatingWebMvcConfiguration
  • 可以 覆盖父类中的 Bean 定义
java 复制代码
@Configuration
public class WebConfig extends DelegatingWebMvcConfiguration {
    // 可以 override 方法,修改默认 Bean
}

适用于需要深度定制 MVC 内部组件的场景。


1.11.14 📄 高级 XML 配置

XML 模式不支持"高级模式",但可通过 BeanPostProcessor 修改已创建的 Bean:

java 复制代码
@Component
public class MyPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String name) {
        if ("requestMappingHandlerAdapter".equals(name)) {
            // 修改适配器配置
        }
        return bean;
    }
}

需配合 <context:component-scan /> 扫描该处理器


✅ 最佳实践建议

配置项 推荐做法
内容协商 禁用路径扩展名匹配,仅使用 Accept
消息转换 使用 Jackson2ObjectMapperBuilder 统一配置 JSON
静态资源 使用资源链 + 内容哈希版本控制
路径匹配 关闭 useSuffixPatternMatchuseTrailingSlashMatch
校验 使用 Hibernate Validator + @Valid
拦截器 按路径精细控制,避免影响静态资源

📚 总结

这份文档是 Spring MVC 配置的核心参考手册,涵盖了从基础启用到高级定制的所有方面。它适用于:

  • 使用纯 Spring(非 Spring Boot)搭建 Web 应用
  • 想要深入了解 Spring MVC 自动配置背后机制的开发者
  • 需要脱离"约定优于配置"模式,进行深度定制的项目

💡 在 Spring Boot 中,这些配置大多由 WebMvcAutoConfiguration 自动完成,开发者只需通过 @Configuration 实现 WebMvcConfigurer 来扩展即可,无需加 @EnableWebMvc(否则会关闭自动配置)。


如果您有具体问题,例如:

  • "如何在 Spring MVC 中统一返回 JSON 格式?"
  • "如何实现静态资源版本控制?"
  • "如何添加登录拦截器?"

欢迎继续提问,我可以基于此文档给出具体代码示例!

相关推荐
会编程的吕洞宾3 小时前
Spring Boot多环境配置实战 配置文件加载顺序与切换不再翻车
java·后端
额鹅恶饿呃3 小时前
随着CentOS官方停服的时间越来越久,大量仍在使用CentOS7的企业和运维从业者
java·python·算法·c#·ruby
秋名RG3 小时前
Java 异常处理全攻略:从入门到实战(JDK 21 版)
java·开发语言
SQL-First布道者3 小时前
我为什么把 MyBatis 从项目中删了?
java·spring·tomcat·mybatis·mybatis plus·spring jdbc
公爵爱学习3 小时前
无人机多点导航笔记
java·前端·笔记
萧瑟余晖4 小时前
Java深入解析篇五十五之Unsafe 机制详解
java
kakawzw4 小时前
mybatis源码笔记1——JDBC和整体架构
java·mybatis
sunshine22 girl4 小时前
Java学习一 环境配置1 安装JDK,配置环境变量
java·开发语言·学习
秋饼4 小时前
Spring AI Session API 深度实战:从 ChatMemory 平滑迁移到事件溯源的企业级短期记忆
java·ai·技术分享·后端开发
QCodingDev4 小时前
Spring AI 2.0企业级RAG实战:引用校验、无依据拒答与知识治理怎么做?
java·人工智能·spring·ai