1、静态资源访问
1.1 静态资源目录
- 只要静态资源放在类路径下:
/static
、/public
、/resources
、/META-INF/resources
这几个文件夹下,都可以通过当前项目根路径/ + 静态资源名
直接访问到。 - 比如,下面
public
文件夹的资源,可以直接通过http://localhost:8080/curley3.jpg
的URI直接访问到。
- 原理:使用了静态映射
/**
,也就是所有包含了所有请求。请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器,静态资源处理器在所有静态资源中找有没有需要的资源,如果有则返回,静态资源也找不到则响应404页面。 - 其中,有两个重要的默认参数
spring: mvc: static-path-pattern: /** resources: static-locations: [classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/]
static-path-pattern
表示静态路径映射,static-locations
表示静态资源地址。 - 通过在配置文件中修改上述两个参数,可以实现只针对指定的映射,用静态资源处理器处理。并且可以指定静态资源所保存的路径。
1.2 webjar
- 之前的静态资源,比如
jQuery
,需要手动下载放在resources
内,而如今可以通过maven的方式添加,自动映射为/webjars/**
。<dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.5.1</version> </dependency>
- 访问地址为
http://localhost:8080/webjars/jquery/3.5.1/jquery.js
,后面地址要按照依赖里面的包路径。 - 在使用jQuery的时候,就可以这样写。
<script type="text/javascript" src="http://localhost:8080/webjars/jquery/3.5.1/jquery.js"></script>
- 更多资源,可以在
https://www.webjars.org/
上找到。
欢迎页访问
- 之前提到的任意一个静态资源目录下放
index.html
文件,都可以直接作为欢迎页被访问。 - 比如,上图已经放了一个
index.html
文件,直接访问地址http://localhost:8080/
,就可以访问到主页。
自定义Favicon
- 浏览器上面会有一个小图标,可以直接下载一个
ico
文件,命名为favicon.ico
放在静态资源目录下,也会被自动加载。
静态资源配置原理
- Spring MVC 在Spring Boot中有一个默认的自动配置类,当我们没有定制一个配置类的时候,默认使用官方的。
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class}) @ConditionalOnMissingBean({WebMvcConfigurationSupport.class}) @AutoConfigureOrder(-2147483638) @AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class}) public class WebMvcAutoConfiguration {
- 里面包含了大部分Spring MVC所需要的组件,在加载的时候,就会将组件放入IOC容器中。
- 在
WebMvcAutoConfiguration
内部,有一个配置类WebMvcAutoConfigurationAdapter
自动加载配置的内容。@Configuration( proxyBeanMethods = false ) @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}) @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class}) @Order(0) public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
ResourceProperties
对应spring.resources
,WebMvcProperties
对应spring.mvc
- 在
WebMvcAutoConfiguration
内部,又有一个配置类EnableWebMvcConfiguration
加载一些资源。
@EnableConfigurationProperties({WebProperties.class}) public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
- 该类继承一个父类
WebMvcConfigurationSupport
,该父类在加载的时候,会调用一个resourceHandlerMapping()
方法,加载一个资源的处理器映射。其中有一个重点方法,this.addResourceHandlers(registry)
,根据静态资源,将静态资源处理器注册。@Bean @Nullable public HandlerMapping resourceHandlerMapping(@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager, @Qualifier("mvcConversionService") FormattingConversionService conversionService, @Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) { Assert.state(this.applicationContext != null, "No ApplicationContext set"); Assert.state(this.servletContext != null, "No ServletContext set"); PathMatchConfigurer pathConfig = this.getPathMatchConfigurer(); ResourceHandlerRegistry registry = new ResourceHandlerRegistry(this.applicationContext, this.servletContext, contentNegotiationManager, pathConfig.getUrlPathHelper()); this.addResourceHandlers(registry); AbstractHandlerMapping handlerMapping = registry.getHandlerMapping(); if (handlerMapping == null) { return null; } else { if (pathConfig.getPatternParser() != null) { handlerMapping.setPatternParser(pathConfig.getPatternParser()); } else { handlerMapping.setUrlPathHelper(pathConfig.getUrlPathHelperOrDefault()); handlerMapping.setPathMatcher(pathConfig.getPathMatcherOrDefault()); } handlerMapping.setInterceptors(this.getInterceptors(conversionService, resourceUrlProvider)); handlerMapping.setCorsConfigurations(this.getCorsConfigurations()); return handlerMapping; } }
- 在
EnableWebMvcConfiguration
中,有该方法重写。静态资源及其映射就此被添加。protected void addResourceHandlers(ResourceHandlerRegistry registry) { super.addResourceHandlers(registry); if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); } else { ServletContext servletContext = this.getServletContext(); this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/"); this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> { registration.addResourceLocations(this.resourceProperties.getStaticLocations()); if (servletContext != null) { registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")}); } }); } }
欢迎页处理规则
- 在
EnableWebMvcConfiguration
中,还有一个返回欢迎页的处理器映射的方法。@Bean public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) { WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern()); welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider)); welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations()); return welcomePageHandlerMapping; }