Spring Boot static resource processing
By default, Spring Boot provides static resource processing, using various attributes configured in WebMvcAutoConfiguration.
We recommend that you use the default configuration method of Spring Boot. If you need special processing, modify the configuration.
To fully control WebMVC, add @ EnableWebMvc (@ SpringBootApplication annotation's program entry class already contains @ Configuration) to the Configuration class of the @ Configuration annotation ), after adding this annotation, the configuration in WebMvcAutoConfiguration will not take effect. You need to configure each item on your own. In this case, you still need to look at the WebMvcAutoConfiguration class.
Since we are using Spring Boot quickly, we don't want to reconfigure it too much. This article mainly focuses on the default Processing Method of Spring Boot. Some configurations are in the application configuration file (. properties or. yml)
Default resource ing
When starting the application, we can see the following information in the console:
2016-01-08 09:29:30.362 INFO 24932 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2016-01-08 09:29:30.362 INFO 24932 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2016-01-08 09:29:30.437 INFO 24932 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
The default/*** configuration maps to/static (or/public,/resources,/META-INF/resources)
The default/webjars/** configuration maps to classpath:/META-INF/resources/webjars/
PS: The above static, public, resources and other directories are all under classpath: (for example, src/main/resources/static ).
If I store images with the same name in the following structure, what is the priority for Spring Boot to read images?
For example:
Which image is shown when we access the address http://www.2cto.com/uploadfile/2016/0112/20160112010740222.jpg? Here, the blogger can tell you the priority order is: META/resources> static> public
If we want to fetch pic2.jpg, request the address http://www.2cto.com/uploadfile/2016/0112/20160112010741409.jpg
Custom Resource ing
The above describes the default resource ing of Spring Boot, which is generally enough. How can we customize directories?
These resources are all packaged in the jar package. In actual application, we still have a lot of resources that are dynamically maintained in the management system and may not be included in the package, how do I access resources that are randomly specified directories?
Custom directory
To add/myres/* Map to classpath:/myres /*The example code is as follows:
The implementation class inherits WebMvcConfigurerAdapter and overrides addResourceHandlers (this is already mentioned in the previous article about interceptor in WebMvcConfigurerAdapter)
package org.springboot.sample.config;import org.springboot.sample.interceptor.MyInterceptor1;import org.springboot.sample.interceptor.MyInterceptor2;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;@Configurationpublic class MyWebAppConfigurer extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/myres/**").addResourceLocations("classpath:/myres/"); super.addResourceHandlers(registry); }}
The address for accessing fengjing.jpg in myres folder is http://www.2cto.com/uploadfile/2016/0112/20160112010743958.jpg
In this way, you can use the code to customize directory ing without affecting the default ing of Spring Boot.
If we set/myres/* Change /*At the same time as the default one, the system configuration will be overwritten. You can use addResourceLocations to add directories multiple times. The priority is higher than the latter.
// Configure the URL of fengjing.jpg under myresroot directory to http://www.2cto.com/uploadfile/2016/0112/20160112010740222.jpg (/** will overwrite the default configuration of the system) // registry. addResourceHandler ("/**"). addResourceLocations ("classpath:/myres /"). addResourceLocations ("classpath:/static /");
The addResourceLocations parameter is an dynamic parameter. You can write addResourceLocations ("classpath:/img1/", "classpath:/img2/", and "classpath:/img3/") in this way /");
Use external directory
If you want to specify an absolute path folder (such as H:/myimgs/), you only need to use addResourceLocations to specify it.
// You can directly use addResourceLocations to specify the absolute disk path. You can also configure multiple locations. Note that file: registry must be added to the path format. addResourceHandler ("/myimgs /**"). addResourceLocations ("file: H:/myimgs /");
Configure through the configuration file
The above code is used to define the ing of static resources. In fact, Spring Boot also provides us with a method that can be directly configured in application. properties (or. yml.
The configuration method is as follows:
# The default value is/** spring. mvc. static-path-pattern = # default value:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/spring. resources. static-locations = the path to be pointed here. Separate multiple paths with commas,
Use spring. mvc. static-path-pattern to redefine pattern, such as modifying to/myres/**, then access the fengjing.jpg file under the static directory should be a http://www.2cto.com/uploadfile/2016/0112/20160112010743958.jpg, before modifying to a http://www.2cto.com/uploadfile/2016/0112/20160112010740222.jpg
Spring. resources. static-locations can be used to redefine the path pointed to by pattern, and supports classpath: and file: (as described above)
Note that only one spring. mvc. static-path-pattern can be defined. Currently, multiple comma-separated methods are not supported.
Use on the page
The above examples also show how to access static resources. In fact, using jsp or freemarker on the page does not have any special features. We can also develop web projects at ordinary times.
Below is my index. jsp:
Use webjars
What is webjars first? In Web development, more and more JS or CSS such as jQuery are used in front-end pages. We usually copy these Web resources to the Java directory, manual copy may produce version errors. If a copy of a version is incorrect, the front-end page cannot be correctly displayed.
WebJars is derived to solve this problem. These Web Front-end resources are packaged into Java Jar packages and managed using Maven dependency libraries to ensure the uniqueness of these Web resource versions.
WebJars is to put js, css and other resource files in classpath:/META-INF/resources/webjars/, and then package it into jar and publish it to the maven repository.
Simple Application
Taking jQuery as an example, the file storage structure is:
META-INF/resources/webjars/jquery/2.1.4/jquery.jsMETA-INF/resources/webjars/jquery/2.1.4/jquery.min.jsMETA-INF/resources/webjars/jquery/2.1.4/jquery.min.mapMETA-INF/resources/webjars/jquery/2.1.4/webjars-requirejs.js
By default, Spring Boot maps/webjars/** to classpath:/META-INF/resources/webjars/, in combination with the rules for accessing resources we mentioned above, we can see that jquery is introduced in the JSP page. the js method is:
<script type="text/javascript" src="${pageContext.request.contextPath }/webjars/jquery/2.1.4/jquery.js"></script>
To achieve this, you only need to add the jquery webjars dependency to the pom. xml file, as shown below:
org.webjars
jquery
2.1.4
Unified Version Management
However, in actual development, we may encounter version upgrades. If we have more than 100 pages, almost every page will introduce jquery as above. js, we need to replace the version number with 3.0.0. One replacement is obviously not the best solution.
How can this problem be solved? Use the following method.
First, add the dependency in pom. xml:
org.webjars
webjars-locator
Then add a WebJarsController:
Package org. springboot. sample. controller; import javax. servlet. http. httpServletRequest; import org. springframework. core. io. classPathResource; import org. springframework. http. httpStatus; import org. springframework. http. responseEntity; import org. springframework. stereotype. controller; import org. springframework. web. bind. annotation. pathVariable; import org. springframework. web. bind. annotation. requestMapping; import org. springframework. web. bind. annotation. responseBody; import org. springframework. web. servlet. handlerMapping; import org. webjars. webJarAssetLocator;/*** process WebJars and automatically read the version number ** @ author single Hongyu (365384722) * @ myblog http://blog.csdn.net/catoop/ * @ create January 8, 2016 */@ Controllerpublic class WebJarsController {private final WebJarAssetLocator assetLocator = new WebJarAssetLocator (); @ ResponseBody @ RequestMapping ("/webjarslocator/{webjar}/**") public ResponseEntityLocateWebjarAsset (@ PathVariable String webjar, HttpServletRequest request) {try {String mvcPrefix = "/webjarslocator/" + webjar + "/"; // This prefix must match the mapping path! String mvcPath = (String) request. getAttribute (HandlerMapping. PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); String fullPath = assetLocator. getFullPath (webjar, mvcPath. substring (mvcPrefix. length (); return new ResponseEntity <> (new ClassPathResource (fullPath), HttpStatus. OK);} catch (Exception e) {return new ResponseEntity <> (HttpStatus. NOT_FOUND );}}}
The method used on the page is as follows:
<script type="text/javascript" src="${pageContext.request.contextPath }/webjarslocator/jquery/jquery.js"></script>
Static resource Version Management
Spring provides support for version ing of static resources by default.
When the content of our resources changes, the user's local resources are still old resources due to browser cache, in order to prevent problems caused by this situation. We may choose to add the parameter "version number" or other methods after the resource file.
Use version number parameters, such:
<script type="text/javascript" src="${pageContext.request.contextPath }/js/common.js?v=1.0.1"></script>
In this way, after the file is modified, manually modify the version number to prevent the URL file from being cached by the browser. There are also many File Modification problems. Or some people will add a timestamp, so I think it is the most undesirable. Every time a browser requests a server, it adds unnecessary pressure.
However, Spring provides two solutions to this problem.
* Resource Name md5 mode *
1. modify the application. properties configuration file (or. yml)
spring.resources.chain.strategy.content.enabled=truespring.resources.chain.strategy.content.paths=/**
All static resources for/** requests are processed.
Create a ResourceUrlProviderController File
Package org. springboot. sample. config; import org. springframework. beans. factory. annotation. autowired; import org. springframework. web. bind. annotation. controllerAdvice; import org. springframework. web. bind. annotation. modelAttribute; import org. springframework. web. servlet. resource. resourceUrlProvider;/*** process static resource URL *** @ author single redwoo (365384722) * @ myblog http://blog.csdn.net/catoop/ * @ create January 8, 2016 */@ your class ResourceUrlProviderController {@ Autowired private ResourceUrlProvider resourceUrlProvider; @ ModelAttribute ("urls") public ResourceUrlProvider urls () {return this. resourceUrlProvider ;}}
Method used on the page
<script type="text/javascript" src="${pageContext.request.contextPath }${urls.getForLookupPath('/js/common.js') }"></script>
After we access the page, the actual code generated in HTML is:
<script type="text/javascript" src="/myspringboot/js/common-c6b7da8fffc9be141b48c073e39c7340.js"></script>
/Myspringboot is the contextPath of my project.
* Resource Version Number Method *
This method does not make much sense and is not described in detail. This is a Unified Version Control for all resources, unlike the above md5 method, which is for files.
In addition to the configuration differences in application. properties (or. yml), the page uses the same as md5.
spring.resources.chain.strategy.fixed.enabled=truespring.resources.chain.strategy.fixed.paths=/js/**,/v1.0.0/**spring.resources.chain.strategy.fixed.version=v1.0.0
After this configuration, the above common. js is used as an example. The actual HTML code generated on the page is:
<script type="text/javascript" src="/myspringboot/v1.0.0/js/common.js"></script>
* Md5 and version number processing principle *
The page first calls the urls. getForLookupPath method, returns a/v1.0.0/js/common. js or/css/common-c6b7da8fffc9be141b48c073e39c7340.js
Then the browser initiates the request.
When the requested address is in the md5 mode, the system will try whether the file name in the url contains-. If the requested address contains-, it will remove the following part and then map the directory (such as/static /) find/js/common. js file. If it can be found, it will be returned.
When the requested address is in version number mode, it will judge whether/v1.0.0 exists in the url. If yes, remove/v1.0.0 from the URL and then map the directory to find the corresponding file, find and return.
Summary
There are so many ways to manage our resource files. However, even in practical applications, it is also possible to use them (there is a reason to exist), but with personal experience.
1. when using third-party libraries, we recommend using the webjars method and using the dynamic version number (webjars-locator) (because the third-party libraries are rarely changed during project development, the version number is changed even if it is changed ).
2. When we use resources stored in the static resource ing directory, we recommend that you use the md5 resource file name (some css and js files in project development will be modified frequently ).
3. we recommend that you put the project material file in the classpath:/static (or other) directory, package it in the project, and maintain images and resources through CMS, we use the absolute path referenced by the configuration to a specific disk.
4. note that Spring has a cache mechanism when using md5 file names. That is to say, you can modify these resource files without restarting the service, the md5 value of the file name does not change. It takes effect only when the service is restarted for another visit. If you need to obtain the actual file's md5 value every time, you need to rewrite the relevant classes for implementation. We do not recommend that you do this because the performance cost is required to always calculate the file's md5 value.