SpringBoot-web Development-Static Resource Rules and Customization

Keywords: Java Spring Boot


Learn sprinboot links

Static Resource Access

1. Static Resource Directories and Prefixes

As long as the static resource is in the class path: /static/public/resources/META-INF/resources
Access: Static resources can be accessed by the current project root path/ +static resource name

Reason: All requests come in and go to Controller first to see if they can be processed. All requests that cannot be processed are handed over to the static resource processor. If the static resource is not found, respond to page 404
springboot defaults to configuring static resources without a prefix, looking for static resources from the / static/public/resources/META-INF/resources folders

spring:
  mvc:
    static-path-pattern: /**
  web:
    resources:
      static-locations: ["classpath:/META-INF/resources/","classpath:/resources/", "classpath:/static/", "classpath:/public/"]

All of the above can be modified in the applicaiton.xml/applicaiton.yaml configuration file if you want to modify the prefix or location of static resources

2.webjar

If we use a jar package to import resources like JQuery, springboot will automatically map / webjars/**

Import method can go webjars website

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.5.1</version>
</dependency>

After importing the jar package, you can see that the file is under / META-INF/resources/webjars/, so we only need to write/webjars/** to access it. For example:http://localhost:8080/webjars/jquery/3.5.1/jquery.js

3.Welcome Pages and Icons

Welcome Page: Find the index.html file in the static content location of the configuration and an index template page in templates. If one is found, it will automatically be used as the welcome page for the application
Icon: The name needs to be favicon.ico, placed in the static resource directory

Note: The static resource prefix cannot be modified, only the default configuration can be used, otherwise it will have no effect

4. Principles of static resource allocation

  • SpringBoot starts loading the xxxAutoConfiguration class by default (AutoConfiguration class)
  • The automatic configuration class WebMvcAutoConfiguration for SpringMVC functionality will also be loaded
    @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 This configuration class adds another configuration class to the container internally
    @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 {
    
    From the @EnableConfiguration Properties annotation, you can see that the classes WebMvcProperties, ResourceProperties, WebProperties are bound to some properties in the configuration file
    WebMvcProperties==spring.mvc
    ResourceProperties==spring.resources
    WebProperties==spring.web
    

4.1. Configuration class has only one parametric constructor

There is only one parametric constructor in this class, WebMvcAutoConfiguration Adapter
Note: The values of all parameters of a parametric constructor are determined from the container

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. Default rules for resource processing

Mapping settings for webjar

As we can see from the addResourceHandlers method in the WebMvcAutoConfiguration Adapter class

  • Judging the value of add-mappings in if (!this.resourceProperties.isAddMappings()) means that all static resource rules below are not in effect if they are returned directly for false.
    So when we set add-mappings to false in ==application.yaml ==all static resource rules will be disabled
  • In addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");This line sets the mapping configuration for 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));
		}
	});
}

Welcome Page Configuration

  • In the WelcomePageHandlerMapping method we can see that the WelcomePageHandlerMapping object was created using a parametric construct
    @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;
    }
    
  • Entering the WelcomePageHandlerMapping class we know why static-path-pattern must be set to /**
    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");
    		}
    	}
    

About favicon

Reason why static resource prefix cannot be set and name needs to be favicon.ico: Browser accesses/favicon.ico when it gets the icon

Posted by Josepheuan on Wed, 08 Sep 2021 14:47:55 -0700