springboot Learning Rules for Static Resource Mapping

Posted by Paulus Magnus on Thu, 29 Aug 2019 12:01:43 +0200

Learning materials reference

B Station Big Man Video

Static resource mapping

webjars

How to import

For some unified resource frameworks, such as jquery,bootstrap, etc., resources can be obtained by importing pom.xml through web jars'official web lookup dependencies
webjars official website

Take jquery as an example

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

How to use it

Ctrl+Shift+R
From the source code, you can see that

 public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
                CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
                if (!registry.hasMappingForPattern("/webjars/**")) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                    ...
                }

Every access to / webjars /** is handled by classpath:/META-INF/resources/webjars/ under the root path, which is also clear in the previous directory structure diagram.

If you want to access static resources, you can access them directly through this mapping (PS: my severPort=8082)

Similarly, in normal use, only importing static resources according to the above static mapping can achieve the desired purpose when needed.

Fuzzy static resource mapping rules

Or the source code of that little bit just now.

...
 String staticPathPattern = this.mvcProperties.getStaticPathPattern();
                if (!registry.hasMappingForPattern(staticPathPattern)) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }
...

Here's the new String []{static Path Pattern} point in which you can finally see
this.staticPathPattern = "/**";
And when this. resourceProperties. getStaticLocations () point goes in, you can finally see private static final String [] CLASSPATH_RESOURCE_LOCATIONS = new String []{"classpath:/META-INF/resources/",""classpath:/resources/","classpath:/static/","classpath:/public/"};
This means that any unprocessed request will arrive
{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"}
Look through these paths

Leave aside / META-INF / in the class directory, for example, any of the following three folders can be accessed directly

Static mapping of welcome pages

In the automatic configuration class WebMvcAutoConfiguration.class of mvc
The Welcome Page Source is like this

  @Bean
        public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext) {
            WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
            welcomePageHandlerMapping.setInterceptors(this.getInterceptors());
            return welcomePageHandlerMapping;
        }

The constructor of the WelcomePageHandlerMapping class is like this

  WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Optional<Resource> welcomePage, String staticPathPattern) {
        if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) {
            logger.info("Adding welcome page: " + welcomePage.get());
            this.setRootViewName("forward:index.html");
        } else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
            logger.info("Adding welcome page template: index");
            this.setRootViewName("index");
        }
 private Optional<Resource> getWelcomePage() {
            String[] locations = WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations());
            return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
        }
..
 private String[] staticLocations;
..
    public ResourceProperties() {
        this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
    ..
    }

This means that when ** is not processed, index.html will be found in String[] CLASSPATH_RESOURCE_LOCATIONS, i.e. {classpath:/META-INF/resources/", `classpath:/resources/', `classpath:/static/', `classpath:/public/'} as a welcome page.

Icons for static mapping

@Bean
            public SimpleUrlHandlerMapping faviconHandlerMapping() {
                SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
                mapping.setOrder(-2147483647);
                mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", this.faviconRequestHandler()));
                return mapping;
            }

Indicates that any favicon.ico will be identified and applied to icon

Topics: JQuery xml