Spring中的ResourceHandler

拽根胡來發表於2019-11-10

Spring Boot 預設配置

在一個Web專案中往往需要處理一些靜態資源的請求,比如css,js,image檔案的等。Spring Boot提供了一種很簡單的方式,即使用預設配置。

在application.properties的配置清單中可以看到這些屬性:

配置項 預設值 含義
spring.resources.add-mappings true Whether to enable default resource handling.
spring.resources.static-locations classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/ Locations of static resources. Defaults to classpath:[/META-INF/resources/, /resources/, /static/, /public/].

也就是說,預設是啟用了靜態資源對映的,並且,當檔案在classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/這四個目錄下的話可以直接返回。

但是,如果開發者不希望將這四個目錄定為靜態資源目錄,而是隻指向某一個(既可以是上面四個目錄其中之一,也可以是一個自定義的目錄),那麼可以修改配置檔案中的上述配置項,或者通過Java程式碼的方式進行配置。

使用Java程式碼配置

首先在Spring的ComponentScan可以掃描到的目錄建立一個WebConfig類,然後重寫addResourceHandlers方法:

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
                .addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/","file:///E:/");
    }
}
複製程式碼

其中,addResourceLocations可以支援新增多個目錄,並且這些目錄型別涵蓋了classpath/file/http:

/**
 * Add one or more resource locations from which to serve static content.
 * Each location must point to a valid directory. Multiple locations may
 * be specified as a comma-separated list, and the locations will be checked
 * for a given resource in the order specified.
 * <p>For example, {{@code "/"}, {@code "classpath:/META-INF/public-web-resources/"}}
 * allows resources to be served both from the web application root and
 * from any JAR on the classpath that contains a
 * {@code /META-INF/public-web-resources/} directory, with resources in the
 * web application root taking precedence.
 * <p>For {@link org.springframework.core.io.UrlResource URL-based resources}
 * (e.g. files, HTTP URLs, etc) this method supports a special prefix to
 * indicate the charset associated with the URL so that relative paths
 * appended to it can be encoded correctly, e.g.
 * {@code [charset=Windows-31J]https://example.org/path}.
 * @return the same {@link ResourceHandlerRegistration} instance, for
 * chained method invocation
 */
public ResourceHandlerRegistration addResourceLocations(String... resourceLocations);
複製程式碼

上面的配置程式碼會覆蓋原來的預設設定,導致預設指定的四個目錄失效。

總結

  1. Spring Boot預設是開啟了靜態資源對映的,並且會掃描四個目錄
  2. 使用Java配置ResourceHandler會覆蓋預設設定
  3. 使用Java配置的程式碼(使用Configration註解的類)必須能被Spring掃描到並載入
  4. addResourceLocations中的地址中可以使用classpath:/。在Spring中src/main/resources目錄下的檔案會直接放到classpath中。當編譯完成時這個目錄下的所有內容應該會輸出到target/classes中,因此classpath:/等同於target/classes/
  5. addResourceLocations可以新增多個目錄,支援的型別有classpath,http,file等。在windows中file目錄的格式參考這裡

相關文章