Spring Boot static resource processing

Source: Internet
Author: User
Tags browser cache

Spring boot static resource processing 8.8 Spring boot static resource processing

When using spring boot to develop a complete system, we often need to use the front-end page, which is indispensable to access to static resources, compared to slices, CSS, JS and other files.

Spring boot uses the configuration of various properties in Webmvcautoconfiguration, which by default provides us with static resource handling. If special handling is required, then the configuration is modified.

Let's take a look at the default configuration inside the Webmvcautoconfiguration class.

Static resource default configuration Webmvcautoconfiguration

There is a Addresourcehandlers method in the Webmvcautoconfiguration class:

        @Override
Public void addresourcehandlers(resourcehandlerregistry registry) {
if(! This. Resourceproperties.isaddmappings ()) {
Logger.debug ("Default Resource handling Disabled");
return;
}
Integer Cacheperiod = This. Resourceproperties.getcacheperiod ();
if(!registry.hasmappingforpattern ("/webjars/**")) {
Customizeresourcehandlerregistration (
Registry.addresourcehandler ("/webjars/**")
. Addresourcelocations (
"classpath:/meta-inf/resources/webjars/")
. Setcacheperiod (Cacheperiod));
}
String Staticpathpattern = This. Mvcproperties.getstaticpathpattern ();
if(!registry.hasmappingforpattern (Staticpathpattern)) {
Customizeresourcehandlerregistration (
Registry.addresourcehandler (Staticpathpattern)
. Addresourcelocations (
This. Resourceproperties.getstaticlocations ())
. Setcacheperiod (Cacheperiod));
}
}

The default processing is done for webjars:

registry.addResourceHandler("/webjars/**")
.addResourceLocations(
"classpath:/META-INF/resources/webjars/")

Where there is no "/**" in the current Resourcehandlerregistry resource map, the Springboot built-in default static resource processing is enabled:

Stringthis.mvcProperties.getStaticPathPattern();//"/**"
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(
this.resourceProperties.getStaticLocations())
.setCachePeriod(cachePeriod));
}

The default static resource mapping path is in the ResourceProperties class, and the relevant code is as follows:

Private Static FinalString[] Classpath_resource_locations = {
"classpath:/meta-inf/resources/","classpath:/resources/",
"classpath:/static/","classpath:/public/"};

Private Static FinalString[] resource_locations;

Static{
Resource_locations =NewString[classpath_resource_locations.length
+ Servlet_resource_locations.length];
System.arraycopy (Servlet_resource_locations,0, Resource_locations,0,
Servlet_resource_locations.length);
System.arraycopy (Classpath_resource_locations,0, Resource_locations,
Servlet_resource_locations.length, classpath_resource_locations.length);
}

/**
* Locations of static resources. Defaults to Classpath:[/meta-inf/resources/,
*/resources/,/static/,/public/] plus context:/ (The root of the servlet context).
*/
Privatestring[] staticlocations = resource_locations;

The default configuration of/** is mapped to the following directory:

classpath:/meta-inf/resources/
classpath:/resources/
classpath:/static/
classpath:/public/

In summary, the Spring Boot default configuration is:

page Request path mode static resources in the path of the project Priority Level
/** classpath:/meta-inf/resources/ 1th Priority
/** classpath:/resources/ 2nd priority
/** classpath:/meta-inf/resources/ 3rd Priority
/** classpath:/static/ 4th priority
/webjars/** classpath:/meta-inf/resources/webjars/ -
Custom Static Resource Mappings

When Springboot integrates swagger, we need to add swagger-ui.html mapping to classpath:/meta-inf/resources/, our custom configuration class, Inherit Webmvcconfigureradapter, and then override the Addresourcehandlers method:

 @Configuration  
@EnableWebMvc//This annotation overrides the default static resource mapping configuration for springboot
webmvcconfig extends webmvcconfigureradapter {
@Override
void addresourcehandlers {

/ /swagger UI Mapping
Registry.addresourcehandler ( "swagger-ui.html" )
. Addresourcelocations ( "classpath:/meta-inf/resources/" )

}< br>
}

If you want to fully control WEBMVC (completely overriding the Springboot default configuration), you need to add @enablewebmvc to the @configuration annotation's configuration class, and when you add @enablewebmvc annotations, Webmvcautoconfiguration in the configuration will not take effect, will automatically overwrite the official given/static,/public, Meta-inf/resources,/resources and other static resources to store the directory. Static resources are located in Src/main/webapp.

It is pointed out in Spring-boot-features.adoc that if your application is to be run as a jar, do not put static resources in the Src/main/webapp directory, although this is the standard directory, but only when the war package played a role. Because most build tools ignore this directory by default when they hit the jar package:

Tip:do not use the src/main/webapp directory if your application'll be packaged as a
Jar. Although this directory was a common standard, it would work with war packaging
And it'll be silently ignored by the most build tools if you generate a jar.

When you need to redefine the directory where the resource resides, you need to proactively add the above configuration class to override the Addresourcehandlers method. You need to configure each of the items you need yourself.

This method will be added on the default basis.

swagger-ui.html Mapping to Classpath:/meta-inf/resources/

Does not affect the default mode and can be used at the same time.

Reference methods for front-end resources

How do you refer to the static resources above in INDEX.FTL?
The recommended default wording is as follows:

<link rel="stylesheet" type="text/css" href="/css/index.css"><script type="text/javascript" src="/js/index.js"></script>

Note: The default configuration of/** maps to/static (or/public,/resources,/meta-inf/resources)

When requesting/css/index.css, Spring MVC is found under the/static/directory.

If configured as/static/js/index.js

<script src="${request.contextPath}/static/js/index.js"></script>

There are no/static directories under the directories configured above, so resource files cannot be found.

At this point, you need to add a custom mapping:

registry.addResourceHandler("/static/**")               .addResourceLocations("classpath:/static/")

So, when we use the Springboot default static resource configuration, write the static resource location without the mapped directory name (such as/static/,/public/,/resources/,/meta-inf/resources/).

Using Webjars

Spring Boot supports the nature of Spring MVC's static resource processing while allowing a reference to a static resource using the jar package version and a static resource that uses a version-independent URL. It is webjars[1].

For example, using jquery, add dependencies:

‘org.webjars.bower‘‘jquery‘‘3.2.1‘

Then, in the front-end HTML code, you can use the following directly:

<script type="text/javascript" src="/webjars/jquery/3.2.1/jquery.js"></script>

You may notice that the 1.11.3 version number in the HREF, if only this use, then when we switch the version number of the time to manually modify the href, it is more troublesome. We can agree on a set of directory rules to pass the dependent version of backend Webjars directly to the backend. The person responsible for completing the directory rules for maintenance management is webjars-locator. Webjars-locator by looking for static resources to load in classpath, and then introducing front-end pages. The way to find the logic of a path is the GetFullPath method in the Webjarassetlocator class.

If we want to use webjars-locator, we need to add dependencies first:

    //Group: org.webjars.bower    // https://mvnrepository.com/artifact/org.webjars/webjars-locator    ‘org.webjars‘‘webjars-locator‘‘0.32‘

Then, add a Webjarcontroller:

Package Com.easy.springboot.h5perf.controller

ImportOrg.springframework.core.io.ClassPathResource
ImportOrg.springframework.http.HttpStatus
ImportOrg.springframework.http.ResponseEntity
ImportOrg.springframework.stereotype.Controller
ImportOrg.springframework.web.bind.annotation.PathVariable
ImportOrg.springframework.web.bind.annotation.RequestMapping
ImportOrg.springframework.web.bind.annotation.ResponseBody
ImportOrg.springframework.web.servlet.HandlerMapping
ImportOrg.webjars.WebJarAssetLocator

ImportJavax.servlet.http.HttpServletRequest

/**
* Created by Jack on 2017/4/22.
*/
@Controller
class webjarscontroller {
Webjarassetlocator Assetlocator =NewWebjarassetlocator ();

@ResponseBody
@RequestMapping ("/webjarslocator/{webjar}/**")
def responseentity<?> Locatewebjarasset (@PathVariableStringWebjar, HttpServletRequest request) {
Try{
StringMvcprefix ="/webjarslocator/"+ Webjar +"/";//This prefix must match the mapping path!
StringMvcpath = (String) Request.getattribute (Handlermapping.path_within_handler_mapping_attribute);
StringFullPath = Assetlocator.getfullpath (Webjar, Mvcpath.substring (Mvcprefix.length ()));
return NewResponseentity<> (NewClasspathresource (FullPath), Httpstatus.ok);
}Catch(Exception e) {
return NewResponseentity<> (Httpstatus.not_found);
}
}
}

The front-end code is then used in the following way:

<link href="${request.contextpath}/webjarslocator/datatables/ Jquery.dataTables.min.css " rel=" stylesheet " type=" Text/css ">
<link href="${request.contextpath}/webjarslocator/tether/tether.min.css" Rel="stylesheet" type="Text/css">
<link href="${request.contextpath}/css/index.css" rel=" Stylesheet " type=" Text/css">
<link href="${request.contextpath}/css/report.css" rel=" Stylesheet " type=" Text/css">

<script src="${request.contextpath}/webjarslocator/jquery/jquery.min.js" ></script>
<script src="${request.contextpath}/js/index.js"></script>

<script src="${request.contextpath}/webjarslocator/tether/tether.min.js"> </script>
<script src="${request.contextpath}/webjarslocator/bootstrap/bootstrap.min.js "></script>
<script src="${request.contextpath}/webjarslocator/datatables/ Jquery.dataTables.min.js "></script>

Here is an example of the template view code for Freemarker. Where the request object is a built-in object. The APPLICATION.YML configuration is as follows:

spring:
# 在freemarker获取request对象
freemarker:
request-context-attribute: request

Note: There is no need to write the version number, but pay attention to write the URL, only the original URL on the basis of the removal of the version number, the other can not be less!

Static resource dynamic version

When the content of our resources changes, because the browser cache, the user's local static resources or old resources, in order to prevent the problem caused by this situation, we request the URL when the version number.

Version numbers such as:

<script type="text/javascript" src="/js/index.js?v=1.0.1"></script>

This version number 1.0.1, can be transmitted from the backend code to the front page ${version}.

Summary

This section focuses on the content of the spring Boot static resource processing. When we are in development, following the default configuration of Springboot, we can greatly reduce the work of our static resource processing.

Complete engineering code for this section:

Https://github.com/EasySpringBoot/h5perf

Resources:

1.webjars:http://www.webjars.org/

Spring Boot static resource processing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.