Spring MVC 和 Spring Boot 是如何访问静态资源的?

Spring MVC 和 Spring Boot 在配置静态资源访问方面有所不同,Spring Boot 提供了更便捷的自动配置。

一、Spring Boot 如何配置静态资源访问 (推荐方式)

Spring Boot 遵循“约定优于配置”的原则,对静态资源的访问提供了非常方便的自动配置。

  1. 默认静态资源位置:
    Spring Boot 会自动从以下类路径 (classpath) 位置查找静态资源:

    • classpath:/META-INF/resources/
    • classpath:/resources/
    • classpath:/static/ (常用)
    • classpath:/public/ (常用)

    优先级顺序: META-INF/resources/ > resources/ > static/ > public/
    这意味着如果你在 src/main/resources/static/ 目录下放一个 style.css 文件,那么你可以通过 http://localhost:8080/style.css 来访问它。

  2. WebJars 支持:
    Spring Boot 也自动支持 WebJars。如果你的项目中引入了 WebJars 依赖(例如 Bootstrap, jQuery),它们会自动从 classpath:/META-INF/resources/webjars/ 提供服务。
    例如,如果引入了 bootstrap.jar,那么它的资源可以通过 http://localhost:8080/webjars/bootstrap/{version}/css/bootstrap.css 访问。

  3. 自定义静态资源位置:
    如果你想使用其他位置,可以在 application.propertiesapplication.yml 中配置:

    # application.properties
    spring.web.resources.static-locations=classpath:/my-custom-static/,classpath:/another-location/
    # 注意:这会覆盖默认位置,如果你还想使用默认位置,需要显式包含它们,例如:
    # spring.web.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/my-custom-static/
    
    # application.yml
    spring:
      web:
        resources:
          static-locations:
            - classpath:/my-custom-static/
            - classpath:/another-location/
            # - classpath:/static/ # 如果覆盖了默认,想保留默认的需要加上
    
  4. 自定义静态资源访问路径前缀:
    默认情况下,静态资源直接从根路径 (/) 开始访问。你可以修改这个前缀:

    # application.properties
    spring.mvc.static-path-pattern=/static-assets/**
    
    # application.yml
    spring:
      mvc:
        static-path-pattern: /static-assets/**
    

    配置后,src/main/resources/static/style.css 对应的访问路径将变为 http://localhost:8080/static-assets/style.css

  5. 缓存控制:
    Spring Boot 允许你配置静态资源的缓存策略:

    # application.properties
    spring.web.resources.cache.period=3600 # 缓存周期,单位秒。设为0禁用缓存。
    spring.web.resources.cache.cachecontrol.max-age=3600
    spring.web.resources.cache.cachecontrol.must-revalidate=true
    # ... 其他 Cache-Control 指令
    
  6. Resource Chain (资源链) - 高级:
    Spring Boot 支持资源链,可以用于版本化资源(在文件名中加入hash值以实现缓存清除)等。

    # application.properties
    spring.web.resources.chain.enabled=true # 通常默认是true
    spring.web.resources.chain.strategy.content.enabled=true # 基于内容的版本策略
    spring.web.resources.chain.strategy.content.paths=/**
    spring.web.resources.chain.strategy.fixed.enabled=true # 固定版本策略
    spring.web.resources.chain.strategy.fixed.paths=/js/lib/
    spring.web.resources.chain.strategy.fixed.version=1.0.0
    

    启用后,你可以在模板(如Thymeleaf)中使用 @{} 语法来获取版本化的URL:<link th:href="@{/css/style.css}" rel="stylesheet"> 会被解析为类似 /css/style-a2c4e1f.css 的路径。

二、“传统” Spring MVC 如何配置静态资源访问

在不使用Spring Boot自动配置的传统Spring MVC项目中,你需要显式配置静态资源处理器。

  1. XML 配置 (spring-mvc-config.xml 或类似文件):
    你需要告诉 DispatcherServlet 将特定模式的请求交给默认的 Servlet 处理器或者专门的资源处理器来处理静态资源,而不是尝试寻找 Controller。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="
               http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/mvc
               http://www.springframework.org/schema/mvc/spring-mvc.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!-- 启用注解驱动的MVC -->
        <mvc:annotation-driven />
    
        <!-- 扫描Controller -->
        <context:component-scan base-package="com.example.controller" />
    
        <!-- 静态资源处理器 -->
        <!-- mapping: 对外暴露的访问路径 -->
        <!-- location: 静态资源在项目中的实际位置 (可以是类路径、文件系统路径或WEB-INF下) -->
        <mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" cache-period="31556926" />
        <mvc:resources mapping="/static/**" location="classpath:/static/" />
        <mvc:resources mapping="/images/**" location="file:///opt/myapp/images/" />
    
        <!-- 如果你的DispatcherServlet映射的是"/" (拦截所有请求),
             你需要这个来让容器的默认Servlet处理未被Spring MVC处理的静态资源请求.
             这对于直接放在webapp根目录下的静态资源有用(不推荐)。 -->
        <mvc:default-servlet-handler />
    
        <!-- 视图解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/" />
            <property name="suffix" value=".jsp" />
        </bean>
    </beans>
    
    • <mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />:
      • mapping: 当请求URL以 /resources/ 开头时,例如 http://localhost:8080/myapp/resources/css/style.css
      • location: Spring会去 webapp/WEB-INF/resources/ 目录下查找对应的 css/style.css 文件。
      • classpath:/static/: 表示从类路径下的 static 目录查找。
    • <mvc:default-servlet-handler />: 如果 DispatcherServlet 映射了 / (即处理所有请求),这个配置会允许容器的默认Servlet处理那些没有被Spring MVC Controller或 <mvc:resources> 匹配到的请求。这通常用于服务那些直接放在 webapp 根目录下的静态文件。
  2. Java 配置 (使用 WebMvcConfigurer):
    如果你使用Java配置,你需要创建一个实现 WebMvcConfigurer 接口的配置类。

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;
    
    @Configuration
    @EnableWebMvc // 启用Spring MVC (等同于XML中的 <mvc:annotation-driven />)
    @ComponentScan(basePackages = "com.example.controller")
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/resources/**") // 对外暴露的访问路径
                    .addResourceLocations("/WEB-INF/resources/") // 实际资源位置
                    .setCachePeriod(31556926); // 缓存周期 (秒)
    
            registry.addResourceHandler("/static/**")
                    .addResourceLocations("classpath:/static/");
    
            registry.addResourceHandler("/images/**")
                    .addResourceLocations("file:///opt/myapp/images/"); // 文件系统路径
    
            // WebJars 支持 (手动配置)
            registry.addResourceHandler("/webjars/**")
                    .addResourceLocations("classpath:/META-INF/resources/webjars/");
        }
    
        // 配置默认的Servlet来处理静态文件 (等同于XML中的 <mvc:default-servlet-handler />)
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
    
        @Bean
        public InternalResourceViewResolver viewResolver() {
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
            resolver.setPrefix("/WEB-INF/jsp/");
            resolver.setSuffix(".jsp");
            return resolver;
        }
    }
    

总结:

  • Spring Boot: 推荐方式。通过自动配置,你只需要将静态资源放在约定的目录 (src/main/resources/static, src/main/resources/public 等) 即可,几乎零配置。自定义也非常简单,通过 application.properties/yml 文件即可。
  • Spring MVC (传统): 需要显式配置。通过XML (<mvc:resources>) 或Java配置 (WebMvcConfigureraddResourceHandlers 方法) 来映射URL到静态资源的位置。

对于新项目,强烈建议使用Spring Boot,因为它极大地简化了包括静态资源在内的各种配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值