Spring 4 - Addresourcehandlers Not Resolving the Static Resources

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



Leave a reply



Submit