SpringBoot-web开发-静态资源规则与定制化
- 静态资源访问
- 1.静态资源目录及前缀
- 2.webjar
- 3. 欢迎页 与 图标
- 4.静态资源配置原理
- 4.1.配置类只有一个有参构造器
- 4.2.资源处理的默认规则
- webjar的映射设置
- 欢迎页的配置
- 关于favicon
静态资源访问
1.静态资源目录及前缀
只要静态资源放在类路径下: /static/public/resources/META-INF/resources
访问 : 当前项目根路径/ + 静态资源名 便可以访问到静态资源
原因:是所有请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面
而springboot默认配置静态资源是无前缀的,从 /static/public/resources/META-INF/resources 四个文件夹下找静态资源
spring:
mvc:
static-path-pattern: /**
web:
resources:
static-locations: ["classpath:/META-INF/resources/","classpath:/resources/", "classpath:/static/", "classpath:/public/"]
所有如果想要修改静态资源的前缀或位置就可以在applicaiton.xml/applicaiton.yaml 配置文件中修改以上两处
2.webjar
如果我们使用了一jar包的形式导入JQuery等资源,springboot会自动映射 /webjars/**
导入方式可以去 webjars官网
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
导入jar包后可以看出 文件是在 /META-INF/resources/webjars/ 下的,所以我们访问时只要写 /webjars/** 就行。如:http://localhost:8080/webjars/jquery/3.5.1/jquery.js
3. 欢迎页 与 图标
欢迎页:在配置的静态内容位置中查找index.html文件与在templates一个index模板页面。如果找到其中之一,它会自动用作应用程序的欢迎页面
图标:名字需要为 favicon.ico ,放在静态资源目录下即可
注意:不可以修改静态资源前缀,只能使用默认的配置,否则没有效果
4.静态资源配置原理
- SpringBoot启动默认加载 xxxAutoConfiguration 类(自动配置类)
- SpringMVC功能的自动配置类 WebMvcAutoConfiguration,也会被加载
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
- WebMvcAutoConfiguration这个配置类内部给容器中又添加了一个配置类
@SuppressWarnings("deprecation")
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class,
org.springframework.boot.autoconfigure.web.ResourceProperties.class, WebProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
- 通过 @EnableConfigurationProperties 这个注解可以看出 WebMvcProperties,ResourceProperties,WebProperties 这几个类都与配置文件中的一些属性进行了绑定
WebMvcProperties==spring.mvc
ResourceProperties==spring.resources
WebProperties==spring.web
4.1.配置类只有一个有参构造器
在WebMvcAutoConfigurationAdapter 这个类中只有一个有参构造器
说明:有参构造器所有参数的值都会从容器中确定
public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties,
ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
ObjectProvider<DispatcherServletPath> dispatcherServletPath,
ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory;
this.messageConvertersProvider = messageConvertersProvider;
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
this.dispatcherServletPath = dispatcherServletPath;
this.servletRegistrations = servletRegistrations;
this.mvcProperties.checkConfiguration();
}
4.2.资源处理的默认规则
webjar的映射设置
在WebMvcAutoConfigurationAdapter 类中addResourceHandlers方法中我们可以看到
- 在if (!this.resourceProperties.isAddMappings()) 中判断add-mappings的值,如果为false的会直接返回,意味着下面的所有静态资源规则不在生效。
所以当我们在==application.yaml == 中将add-mappings设置为false将禁用所有静态资源规则 - 在addResourceHandler(registry, “/webjars/**”, “classpath:/META-INF/resources/webjars/”); 这行中设置了webjar的映射配置。
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
ServletContext servletContext = getServletContext();
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (servletContext != null) {
registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
}
});
}
欢迎页的配置
- 在WelcomePageHandlerMapping 方法中我们可以看到使用了有参构造创建了WelcomePageHandlerMapping对象
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
return welcomePageHandlerMapping;
}
- 进入WelcomePageHandlerMapping类中 我们知道了为什么一定要将static-path-pattern设置为/**
WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
if (welcomePage != null && "/**".equals(staticPathPattern)) {
logger.info("Adding welcome page: " + welcomePage);
setRootViewName("forward:index.html");
}
else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
logger.info("Adding welcome page template: index");
setRootViewName("index");
}
}
关于favicon
为什么不能设置静态资源前缀且名称需要为favicon.ico的原因:浏览器获取图标时是访问/favicon.ico