SpringBoot的静态资源处理
测试
1、静态资源访问
官网说明如下:
默认情况下,Spring Boot 从 Classpath 中名为
/static(或/public或/resources或/META-INF/resources)的目录或ServletContext的根目录中提供静态内容。它使用 Spring MVC 中的ResourceHttpRequestHandler,因此您可以通过添加自己的WebMvcConfigurer并覆盖addResourceHandlers方法来修改该行为。在独立的 Web 应用程序中,还启用了容器中的默认 servlet,并将其用作后备,如果 Spring 决定不处理
ServletContext的根,则从ServletContext的根开始提供内容。在大多数情况下,这不会发生(除非您修改默认的 MVC 配置),因为 Spring 始终可以通过DispatcherServlet处理请求。默认情况下,资源 Map 在
/**上,但是您可以使用spring.mvc.static-path-pattern属性对其进行调整。例如,将所有资源重定位到/resources/**可以实现如下:spring.mvc.static-path-pattern=/resources/**您还可以使用
spring.resources.static-locations属性来自定义静态资源位置(用目录位置列表替换默认值)。根 Servlet 上下文路径"/"也会自动添加为位置。除了前面提到的“标准”静态资源位置以外,还对Webjars content进行了特殊处理。如果 jar 文件以 Webjars 格式打包,则从 jar 文件提供带有
/webjars/**路径的任何资源。如果您的应用程序打包为 jar,则不要使用
src/main/webapp目录。尽管此目录是一个通用标准,但它仅在 war 打包中有效,并且在生成 jar 时,大多数构建工具都将其忽略。Spring Boot 还支持 Spring MVC 提供的高级资源处理功能,允许使用案例,例如缓存清除静态资源或对 Webjars 使用版本无关的 URL。
要对 Webjar 使用版本无关的 URL,请添加
webjars-locator-core依赖项。然后声明您的 Webjar。以 jQuery 为例,在"/webjars/jquery/x.y.z/jquery.min.js"中添加"/webjars/jquery/jquery.min.js"结果。其中x.y.z是 Webjar 版本。
进行测试:
静态资源目录

进行测试的时候,由于之前项目引入了手写的sarter,里面有个拦截器,对所有资源进行拦截,导致访问不到静态资源,需要方向。
 
由于静态资源默认的映射是/**,为了方便拦截器放行,这里可以自定义。
spring:
  mvc:
    static-path-pattern: /res/**
 
官网也说明了,可以自定义静态资源路径
spring:
  mvc:
    static-path-pattern: /res/**   ##这里是加的请求的路径
  resources:
    static-locations: [classpath:/test/]  ## 这里是隐射的路径
 
注意,这里数组只写一个的话,会把其他几个路径覆盖掉。
webjar
      <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.5.1</version>
        </dependency>

进行测试
http://localhost:8888/webjars/jquery/3.5.1/webjars-requirejs.js
2、欢迎页支持
- 
静态资源路径下 index.html 
- 
- 可以配置静态资源路径
- 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默
 

要注释掉下面配置,因为在源码中,有了判断,不然不生效
#spring:
#  mvc:
#    static-path-pattern: /res/**
3、自定义 Favicon
favicon.ico 放在静态资源目录下即可。

源码
- 
因为springboot自动配置的原因,引入了很多自动配置类,所以先找到入口WebMvcAutoConfiguration  
- 
查看这个配置类生效的前提条件,其中发现了 WebMvcConfigurationSupport.class. @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 {如果自己全部接管mvc的,可以使用@EnableWebMvc这个注解,它其实会往IOC容器注入DelegatingWebMvcConfiguration,它继承了WebMvcConfigurationSupport。 
- 
都是在容器中找WebMvcAutoConfigurationAdapter这个类 //有参构造器所有参数的值都会从容器中确定 //ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象 //WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象 //ListableBeanFactory beanFactory Spring的beanFactory //HttpMessageConverters 找到所有的HttpMessageConverters //ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。========= //DispatcherServletPath //ServletRegistrationBean 给应用注册Servlet、Filter.... 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(); }
资源处理的默认规则
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
			super.addResourceHandlers(registry);
            //如果在yaml里面配置的false,则静态资源全部失效
			if (!this.resourceProperties.isAddMappings()) {
				logger.debug("Default resource handling disabled");
				return;
			}
			ServletContext servletContext = getServletContext();
            //这里配置的就是webjars资源映射
			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));
				}
			});
		}
		private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
			addResourceHandler(registry, pattern, (registration) -> registration.addResourceLocations(locations));
		}
		private void addResourceHandler(ResourceHandlerRegistry registry, String pattern,
				Consumer<ResourceHandlerRegistration> customizer) {
			if (registry.hasMappingForPattern(pattern)) {
				return;
			}
			ResourceHandlerRegistration registration = registry.addResourceHandler(pattern);
			customizer.accept(registration);
			registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
			registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
			customizeResourceHandlerRegistration(registration);
		}


注:如果请求的静态资源和请求的接口是同一个路径,则优先处理接口
3、欢迎页的处理规则
		@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(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");
		}
	}

注:如果这里配置了静态资源路径,会导致欢迎页失效,如果没有失效,则请重定向到Index.html

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号