靜態資源映射規則、定制首頁、定制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

比如:我們訪問:localhost:8080/1.js,因為上面匹配的模式是:/**,而用於存放靜態資源的路徑是以上四個;所以它會自動幫我們去找這四個路徑中對應的靜態文件。
我們也可以在 application.yaml 中自定義靜態資源映射路徑:
spring:
resources:
# 自定義靜態資源映射路徑,SpringBoot默認的 4種即失效
static-locations: classpath:/rainszj/, classpath:/hello/

定制首頁
繼續看WebMvcAtuoConfiguration這個自動配置類

只要我們的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 文件夾,放置表示 相應狀態碼 的頁面。

對於更復雜的映射,還可以添加實現 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>

配置 icon

在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即可

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

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