springboot 2.X 在訪問靜態資源的的時候出現404的問題


通過idea快速搭建一個springboot項目:

springboot版本2.1.6

在網上看的資料,springboot靜態資源訪問如下:

"classpath:/META‐INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"
"/":當前項目的根路徑

之后在測試訪問靜態資源的時候沒有問題,通過代碼配置的方式訪問登錄頁面資源的時候出現了404。

在網上找了很多關於靜態資源訪問404的問題,貌似不是在application.yml(或properties)中配置訪問路徑,就是自己定義config類。

后來翻看源碼發現,由於在代碼配置的時候。繼承了WebMvcConfigurationSupport這個類,導致整個資源訪問失效,具體原因如下:

第一步:

  確認springboot靜態資源訪問的位置,由於springboot自動加載配置,所以找到WebMvcAutoConfiguration這個配置類,里面有很多方法,

  只需找到資源映射的方法:

public void addResourceHandlers(ResourceHandlerRegistry registry) {
  if (!this.resourceProperties.isAddMappings()) {
    logger.debug("Default resource handling disabled");
  } else {
    Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
    CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
    <!-- /webjars/** 訪問的,資源映射規則-->
    if (!registry.hasMappingForPattern("/webjars/**")) {       this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).
          addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));     }      <!-- 靜態資源映射規則-->     String staticPathPattern = this.mvcProperties.getStaticPathPattern();     if (!registry.hasMappingForPattern(staticPathPattern)) {       this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).
          addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).
                    setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));      }    } }

 第一種webjars加載:所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找資源;

  第二種靜態資源映射:

  staticPathPattern  點擊查看源碼:staticPathPattern = /**;

  resourceProperties.getStaticLocations() 點擊查看源碼:

 private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
    private String[] staticLocations;
    private boolean addMappings;
    private final ResourceProperties.Chain chain;
    private final ResourceProperties.Cache cache;

    public ResourceProperties() {
        this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
        this.addMappings = true;
        this.chain = new ResourceProperties.Chain();
        this.cache = new ResourceProperties.Cache();
    }

    public String[] getStaticLocations() {
        return this.staticLocations;
    }

 

通過以上源碼看出,訪問資源路徑跟一開始測試時的一樣,沒問題,為何通過配置設置登錄頁面就無法訪問靜態資源了呢,反復查看WebMvcAutoConfiguration源碼發現如下:

@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class}) @ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {=
@ConditionalOnClass@ConditionalOnMissingBean 這兩個注解的條件成立WebMvcAutoConfiguration才會自動加載,
在配置登錄頁的時候,正好繼承了WebMvcConfigurationSupport

@ConditionalOnMissingBean({WebMvcConfigurationSupport.class}) 容器沒有加載這個bean時自動加載WebMvcAutoConfiguration,
繼承WebMvcAutoConfiguration的方式也可以,不過需要手動添加資源映射路徑,WebMvcAutoConfiguration中的其他自動加載項也需要自己處理。

@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class}) 容器加載這個bean時自動加載WebMvcAutoConfiguration
重新修改配置類 實現WebMvcConfigurer接口對登錄頁進行處理,靜態資源訪問正常。

 

   

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM