SpringBoot:靜態資源映射、定制404、配置icon


靜態資源映射規則、定制首頁、定制404頁面、配置網站的圖標

靜態資源映射規則

SpringBoot中對於靜態資源(css,js,img....)的存放是有規定的;

在SpringBoot中,SpringMVC的web配置都在 WebMvcAtuoConfiguration這個自動配置類中,在其中有個靜態內部類,也就是自動配置適配器:WebMvcAutoConfigurationAdapter,其中有個添加資源處理器方法addResourceHandlers,該方法是用來提供靜態資源

public void addResourceHandlers(ResourceHandlerRegistry registry) {
 	 // 判斷有沒有自定義映射規則
   if (!this.resourceProperties.isAddMappings()) {
      logger.debug("Default resource handling disabled");
      return;
   }
   Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
   CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
  // 判斷是否使用 webjars 方式,所有的 /webjars/**,都需要去 classpath:/META-INF/resources/webjars/ 找對應的資源
   if (!registry.hasMappingForPattern("/webjars/**")) {
      customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
            .addResourceLocations("classpath:/META-INF/resources/webjars/")
            .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
   }
  // 默認靜態資源映射路徑
  // 點擊去 getStaticPathPattern()方法
   String staticPathPattern = this.mvcProperties.getStaticPathPattern();
   if (!registry.hasMappingForPattern(staticPathPattern)) {
      customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
            .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
            .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
   }
}

去找 staticPathPattern

/**
 * 用於靜態資源的路徑模式
 */
private String staticPathPattern = "/**";

/** 會訪問當前的項目任意資源,它會去找 resourceProperties 這個類,我們可以點進去看一下

@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {

   private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
         "classpath:/resources/", "classpath:/static/", "classpath:/public/" };

   /**
    * 靜態資源的位置. 默認會到 classpath:[/META-INF/resources/,
    * /resources/, /static/, /public/].
    */
   private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;

所以得出結論:我們可以在 resources 的根目錄下新建對應的文件夾,來存放我們對應的靜態文件,它們的訪問優先級依次從高到低如下:

"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
 其中 "/":代表當前項目的根目錄

這里的 classpath 代指 resources

1582183519093.png

比如:我們訪問:localhost:8080/1.js,因為上面匹配的模式是:/**,而用於存放靜態資源的路徑是以上四個;所以它會自動幫我們去找這四個路徑中對應的靜態文件。

我們也可以在 application.yaml 中自定義靜態資源映射路徑:

spring:
  resources:
    # 自定義靜態資源映射路徑,SpringBoot默認的 4種即失效
    static-locations: classpath:/rainszj/, classpath:/hello/

1582185259086.png

定制首頁

繼續看WebMvcAtuoConfiguration這個自動配置類

1582184470590.png

只要我們的index.html在上面的4種 classpath 靜態資源映射路徑中,訪問時就會自動去尋找。

例如,我們訪問:localhost:8080/ 或者 localhost:8080/index.html 它會自動幫我們去尋找到該頁面。

定制錯誤頁面

如果要顯示給定狀態代碼的自定義HTML錯誤頁,可以將文件添加到/error文件夾。錯誤頁可以是靜態HTML(即添加到任何靜態資源文件夾下)或使用模板生成。文件名應為確切的狀態代碼或序列掩碼。

例如,要將404映射到靜態HTML文件,文件夾結構如下:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

即:我們只需在靜態資源路徑下 新建 error 文件夾,放置表示 相應狀態碼 的頁面。

1582190183282.png

對於更復雜的映射,還可以添加實現 ErrorViewResolve接口的bean,如下例所示:

public class MyErrorViewResolver implements ErrorViewResolver {
    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request,
                                         HttpStatus status, Map<String, Object> model) {

        ModelAndView mv = new ModelAndView();

        if (status.is4xxClientError()) {
          	// 設置視圖名稱,此處需要使用 thymeleaf 模板引擎的jar包
          	// 該視圖放置到 templates 目錄下 
            mv.setViewName("404");
        }

        return mv;
    }
}

添加bean:

/**
 * 擴展 MVC
 */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    /**
     * 注冊Bean
     * @return
     */
    @Bean
    public ErrorViewResolver myErrorViewResolver() {
        return new MyErrorViewResolver();
    }

}

在 pom.xml 中添加 thymeleaf 的依賴

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

1582190089544.png

配置 icon

1582185750947.png

在Spring Boot項目的issues中提出,如果提供默認的Favicon可能會導致網站信息泄露。如果用戶不進行自定義的Favicon的設置,而Spring Boot項目會提供默認的上圖圖標,那么勢必會導致泄露網站的開發框架。
因此,在Spring Boot2.2.x中,將默認的favicon.ico移除,同時也不再提供上述application.properties中的屬性配置。

在SpringBoot 2.2.4 版本,沒有 如下這個圖標配置類了,為此我們使用 2.1.7版本

   @Configuration
   @ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
   public static class FaviconConfiguration implements ResourceLoaderAware {

      private final ResourceProperties resourceProperties;

      private ResourceLoader resourceLoader;

      public FaviconConfiguration(ResourceProperties resourceProperties) {
         this.resourceProperties = resourceProperties;
      }

      @Override
      public void setResourceLoader(ResourceLoader resourceLoader) {
         this.resourceLoader = resourceLoader;
      }

      @Bean
      public SimpleUrlHandlerMapping faviconHandlerMapping() {
         SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
         mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
         mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", faviconRequestHandler()));
         return mapping;
      }

      @Bean
      public ResourceHttpRequestHandler faviconRequestHandler() {
         ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
         requestHandler.setLocations(resolveFaviconLocations());
         return requestHandler;
      }

      private List<Resource> resolveFaviconLocations() {
         String[] staticLocations = getResourceLocations(this.resourceProperties.getStaticLocations());
         List<Resource> locations = new ArrayList<>(staticLocations.length + 1);
         Arrays.stream(staticLocations).map(this.resourceLoader::getResource).forEach(locations::add);
         locations.add(new ClassPathResource("/"));
         return Collections.unmodifiableList(locations);
      }

   }

}

切換SpringBoot版本,只需要修改 pom.xml中的 parent 中的 version即可

1582186710183.png

配置 ico 只需兩步,放置ico,在 application.yaml 中關閉默認的圖標,圖標名稱必須為:favicon.ico

1582186968549.png

application.yaml

spring:
  mvc:
    favicon:
      enabled=false	# 關閉默認的圖標


免責聲明!

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



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