SpringBoot-web开发-静态资源规则与定制化

  • 静态资源访问
  • 1.静态资源目录及前缀
  • 2.webjar
  • 3. 欢迎页 与 图标
  • 4.静态资源配置原理
  • 4.1.配置类只有一个有参构造器
  • 4.2.资源处理的默认规则
  • webjar的映射设置
  • 欢迎页的配置
  • 关于favicon



学习sprinboot链接

静态资源访问

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

springboot MVC设置静态资源路径 springboot指定静态资源路径_jar

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