Spring 4 - addResourceHandlers not resolving the static resources
this worked,
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
and in the jsp files I referred to the static resources like
<link href="resources/css/bootstrap.css" rel="stylesheet" media="screen">
Spring - addResourceHandlers not resolving the static resources with Rest Controller
I found a way to set the priority of the ResourceHandler.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Register resource handler for CSS and JS
registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/")
.setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic())
.resourceChain(true)
.addResolver(new PathResourceResolver());
// Register resource handler for images
registry.addResourceHandler("/images/**").addResourceLocations("/WEB-INF/images/")
.setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic())
.resourceChain(true)
.addResolver(new PathResourceResolver());
registry.setOrder(-1); // This will set the priority lower to the default handler (that is by default 0)
}
Spring Boot 2.4 application doesn't resolve static content with custom WebMvcConfigurer#addResourceHandlers
The resource/class path resolving is indeed confusing and it took me also a bit to get behind it. The following example with a lot of comments hopefully clarifies everything.
TL;DR:
registry
// Request URLs
.addResourceHandler("/**" /*, ... */)
// Path inside application (refers to src/main/resources directory)
// TRAILING SLASH IS IMPORTANT
.addResourceLocations("classpath:/static/")
Spring appends the variable portion of the path from the pattern one puts into addResourceHandler()
to the ressource locations provided in .addResourceLocations()
. Example:
// TRAILING SLASH IS IMPORTANT!
.addResourceLocations("classpath:/static/")
=>
addResourceHandler("/**")
=> GET /res/css/main.css
=> resolved as: "classpath:/static/res/css/main.css"
BUT
addResourceHandler("/res/**")
=> GET /res/css/main.css
(spring only appends the ** to the value from
addResourceLocations())
=> resolved as: "classpath:/static/css/main.css"
Working Example Configuration
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.concurrent.TimeUnit;
@Configuration
public class CacheStaticResourcesConfiguration implements WebMvcConfigurer {
/**
* We provide a custom configuration which resolves URL-Requests to static files in the
* classpath (src/main/resources directory).
*
* This overloads a default configuration retrieved at least partly from
* {@link WebProperties.Resources#getStaticLocations()}.
*
* @param registry ResourceHandlerRegistry
*/
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
/*
* BE AWARE HERE:
*
* .addResourceHandler(): URL Paths
* .addResourceLocations(): Paths in Classpath to look for file
* root "/" refers to src/main/resources
* For configuration example, see:
* org.springframework.boot.autoconfigure.web.WebProperties.Resources().getStaticLocations()
*
* .addResourceLocations("classpath:/static/")
* =>
* addResourceHandler("/**")
* => GET /res/css/main.css
* => resolved as: "classpath:/static/res/css/main.css"
* BUT
* addResourceHandler("/res/**")
* => GET /res/css/main.css
* (spring only appends the ** to the value from
* addResourceLocations())
* => resolved as: "classpath:/static/css/main.css"
*/
registry
.addResourceHandler("/favicon.ico")
// trailing slash is important!
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)
.noTransform()
.mustRevalidate());
registry
.addResourceHandler("/res/**")
// trailing slash is important!
.addResourceLocations("classpath:/static/res/")
.setCacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)
.noTransform()
.mustRevalidate());
registry
.addResourceHandler("/images/**")
// trailing slash is important!
.addResourceLocations("classpath:/static/images/")
.setCacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)
.noTransform()
.mustRevalidate());
}
}
Spring Boot static resources are not available
You should add below line to your existing resource mapping:
registry.addResourceHandler("/**")
.addResourceLocations("resources/static/");
You have configured the webjars resourceHandler to serve client side script or stylesheet dependencies. but custom handler is not added to serve your image file.
Since you are overriding the addResourceHandlers (ResourceHandlerRegistry registry)
method, you should provide all the resourceLocation and handler mapping in your implementation.
Please check serving-static-web-content-with-spring-boot article to have more clear idea.
Note:
If you are using spring-boot you shouldn't be overriding the above method untill explicitly required as its already taken care in WebMvcAutoConfiguration.java
.
Please check below default implementation:
@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();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(
this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
}
Spring 4 loading static resources
You say that your stylesheets and JavaScript files are under "/assets". I'm going to assume you have directories "/assets/css" and "/assets/js". Then, given the following resource handler definition:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/assets/**")
.addResourceLocations("classpath:/assets/");
}
You would load these resources in your HTML like so:
<link href="/assets/css/style.css" rel="stylesheet" />
<script src="/assets/js/general.js"></script>
Related Topics
Get Integer Value of the Current Year in Java
How to Use Classloader.Getresources() Correctly
Configure Datasource Programmatically in Spring Boot
Java Command Line with External .Jar
How to Get Http Response Code for a Url in Java
Uninitialized Object VS Object Initialized to Null
Is It Necessary to Close Each Nested Outputstream and Writer Separately
Why Never Change the Notifier in Receiving a Change Event
What Is the Best Library for Java to Grid/Cluster-Enable Your Application
What Are the Differences Between Char Literals '\N' and '\R' in Java
Javax.Mail.Authenticationfailedexception Is Thrown While Sending Email in Java
When Does the Main Thread Stop in Java