SpringBoot2 - Static Resource Mapping Rule

Posted by Tedglen2 on Sun, 02 Jan 2022 07:52:16 +0100

1. Static Resource Access

1.0 View the corresponding description of the official website documents

static content corresponds to the relevant content

1.1 Static Resource Directory

  • "/**" Accesses any resource (folder of static resources) in the current project

  • By default, as long as the static resource is in the class path: called/static (or/public or/resources or/META-INF/resources)
  • Access: Current project root path/ +static resource name
  • Principle: Static Mapping/**
  • Please come in and go to Controller first to see if you can handle it. All requests that cannot be processed are handed over to the static resource processor. Response 404 page if static resource is not found

Static resource access path priority:
META-INF/resources
resources
static
public

1.2 Static Resource Access Prefix

Default No Prefix

spring:
  mvc:
    static-path-pattern: /res/**

Current project + static-path-pattern + static resource name = under static resource folder

In order to distinguish static resources from dynamic resources during interception, a prefix is prefixed to static resources, and the interceptor releases when it sees the specified prefix, so as to achieve the purpose of dynamic static separation.

Note: When static resources are accessed with a prefix, they must be prefixed. This is used by interceptors to intercept static resources.

1.3 Change the default static resource path - specify under which path all static resources are placed

spring:
  mvc:
    static-path-pattern: /res/**

  web:
    resources:
      static-locations:  [classpath:/haha/]

Note: After specifying the location of the new static resource folder, the springboot default will not take effect, that is, we will access the static resource through the location of the folder we specified, which was previously inaccessible

2.1 Welcome Page Support

Index under static resource path. HTML

  • Static resource paths can be configured
  • However, you cannot configure the access prefix for static resources. Otherwise, it results in an index.html cannot be accessed by default
spring:
#  mvc:
#    static-path-pattern: /res/** This will invalidate welcome page functionality

  resources:
    static-locations: [classpath:/haha/]
  • controller can handle/index

2.2 Custom Favicon

favicon.ico is placed in the static resource directory and must be named favicon

spring:
#  mvc:
#    static-path-pattern: /res/** This will invalidate Favicon functionality

2.3. Principles of static resource allocation

  • SpringBoot starts loading the xxxAutoConfiguration class by default (AutoConfiguration class)
  • AutoConfiguration class WebMvcAutoConfiguration for SpringMVC functionality, effective
@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 {}

What has been added to the container.

	@Configuration(proxyBeanMethods = false)
	@Import(EnableWebMvcConfiguration.class)
	@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
	@Order(0)
	public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}
  • The properties associated with the configuration file are bound to xxx.
  • WebMvcProperties==spring.mvc,
  • ResourceProperties==spring.resources

1. Configuration class has only one parametric constructor

	//The values of all parameters of the parametric constructor are determined from the container
//ResourceProperties resourceProperties; Get and spring. Object for all values bound by resources
//WebMvcProperties mvcProperties Get and Spring. Object for all values bound by MVC
//BeanFactory for ListableBeanFactory beanFactory Spring
//HttpMessageConverters found all HttpMessageConverters
//ResourceHandlerRegistrationCustomizer found the customizer for the resource processor. =======
//DispatcherServletPath  
//ServletRegistrationBean registers Servlets, Filter s, etc. for applications.
	public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties,
				ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
				ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
				ObjectProvider<DispatcherServletPath> dispatcherServletPath,
				ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
			this.resourceProperties = resourceProperties;
			this.mvcProperties = mvcProperties;
			this.beanFactory = beanFactory;
			this.messageConvertersProvider = messageConvertersProvider;
			this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
			this.dispatcherServletPath = dispatcherServletPath;
			this.servletRegistrations = servletRegistrations;
		}

2. Default Rules for Resource Processing

@Override
		public void addResourceHandlers(ResourceHandlerRegistry registry) {
			if (!this.resourceProperties.isAddMappings()) {
				logger.debug("Default resource handling disabled");
				return;
			}
			Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
			CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
			//Rules for webjars
            if (!registry.hasMappingForPattern("/webjars/**")) {
				customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
						.addResourceLocations("classpath:/META-INF/resources/webjars/")
						.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
			}
            
            //The static resource path is taken from the configuration file and there are no four default paths available
			String staticPathPattern = this.mvcProperties.getStaticPathPattern();
			if (!registry.hasMappingForPattern(staticPathPattern)) {
				customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
						.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
						.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
			}
		}
spring:
#  mvc:
#    static-path-pattern: /res/**

  resources:
    add-mappings: false   Disable all static resource rules

There are four default static resource paths

@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {

	private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
			"classpath:/resources/", "classpath:/static/", "classpath:/public/" };

	/**
	 * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
	 * /resources/, /static/, /public/].
	 */
	private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;

3. Processing rules for welcome pages

	HandlerMapping: Processor mapping. Save every Handler Which requests can be processed.	

	@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, Optional<Resource> welcomePage, String staticPathPattern) {
			//Here the bottom level writes the access path to the dead welcome page
		if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) {
            //To use the Welcome Page feature, you must be /**
			logger.info("Adding welcome page: " + welcomePage.get());
			setRootViewName("forward:index.html");
		}
		else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
            // Call Controller/index
			logger.info("Adding welcome page template: index");
			setRootViewName("index");
		}
	}

4,favicon

The browser sends/favicon requests for icons, which are no longer available throughout the session, so the icon name under the static resource folder is fixed