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 格式?"
  • "如何实现静态资源版本控制?"
  • "如何添加登录拦截器?"

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

相关推荐
せいしゅん青春之我8 小时前
【JavaEE初阶】TCP核心机制10——异常情况的处理
java·网络·笔记·网络协议·tcp/ip·java-ee
摇滚侠8 小时前
Spring Boot3零基础教程,把 Java 程序打包为 Linux 可执行文件,笔记91
java·linux·笔记
mount_myj8 小时前
敏感信息屏蔽(一)【java】
java·算法·极课堂
Zhangzy@8 小时前
Rust 内存对齐与缓存友好设计
spring·缓存·rust
四谎真好看9 小时前
Java 黑马程序员学习笔记(进阶篇21)
java·开发语言·笔记·学习·学习笔记
Dnui_King9 小时前
Kingbase 接口兼容性测试
java
Java&Develop9 小时前
IDEA报错:前言中不允许有内容
java
软件架构师-叶秋9 小时前
spring boot入门篇之开发环境搭建
java·spring boot·后端
qq_3002406310 小时前
spring cache 支持多结构的 Redis 缓存管理器
spring·缓存