Spring MVC: Is regular expression possible to map static contents in WebMvcConfigurerAdapter - spring

I want to make a dynamic key for my static resource, here is my application
I have a web application (Spring MVC), most of its jsp pages serve static resource like images, js and css etc, These resources are cached. So whenever I modify css or js, I just change that key so that web page request for files on different new path.
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.my.package" })
public class AppConfig extends WebMvcConfigurerAdapter {
//... some code ...
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/here-is-a-key/resource/**")
.addResourceLocations("/static/")
.setCachePeriod(2592000);//30 days
}
//... some code ...
}
This will serve static resource like
/static/here-is-a-key/resource/js/app.js
Whenever I make changes in static resources (images,css, js), I also change the key
This helps browser or webpage to request fresh resources. (not cached)
It works perfect,
but issue comes for the servers or browsers that caches the html page(google etc), in that cached html page the key saved was old-key which does not map anything anymore, and 404 exception is thrown.
I want this part to be ignored some wild-card functionality
registry.addResourceHandler("/static/(.*?)/resource/**")
.addResourceLocations("/static/")
so that it matches cached path as well as new path.
So any contents like
/static/key001/resources/** get mapped to /static/
/static/key002/resources/** also mapped on /static/

Related

Automatically finding Thymeleaf templates with Spring Boot

How can I get Spring Boot and Thymeleaf to automatically find and map template files to be processed when accessed by the browser?
src/main/resources/templates/index.xhtml
src/main/resources/templates/bar.xhtml
src/main/resources/application.properties contains spring.thymeleaf.suffix=.xhtml
FooController.java contains #RequestMapping("/foo") and a #PostMapping method that returns bar
If I enter http://localhost:8080/ in the browser, Thymeleaf processes and displays the index.xhtml page with no extra configuration needed. But http://localhost:8080/index, http://localhost:8080/index.xhtml, and http://localhost:8080/index.html all result in 404 Not Found.
My index view does a POST to foo; FooController is activated and returns bar; and Thymeleaf processes and shows bar.xhtml, even though bar.xhtml isn't mapped anywhere in the configuration. Yet accessing http://localhost:8080/bar, http://localhost:8080/bar.xhtml, and http://localhost:8080/bar.html in a browser all result in 404 Not Found.
Why does GET http://localhost:8080/ process the index.xhtml template, but GET http://localhost:8080/index does not?
How can Thymleaf use bar as a view, but I cannot access http://localhost:8080/bar directly?
How can I configure Thymeleaf so that I can add src/main/resources/templates/example.xhtml and have it processed automatically as a template that I can access via http://localhost:8080/example in the browser, with no explicit configuration specifically for the example.xhtml file?
If I absolutely have to configure controllers (see my answer below), is there a way that I can at least do this in some declarative file, outside of my code?
As noted in Spring in Action, Fifth Edition, I can do something like this in a #Configuration class that implements WebMvcConfigurer
#Override
public void addViewControllers(final ViewControllerRegistry registry) {
registry.addViewController("/bar");
}
That will allow me to process bar.xhtml automatically. (I presume there is some default configuration registry.addViewController("/").setViewName("index"), which is why my index.xhtml file is getting processed by accessing the root path.
And I can even use the following to automatically pick up any template:
#Override
public void addViewControllers(final ViewControllerRegistry registry) {
registry.addViewController("/**");
}
Unfortunately this removes the mapping from / to /index, and also prevents accessing any static resources from src/main/resources. I'm not sure how to tell Thymeleaf to use a template if it can, and fall back to a static file if not.

Static resources arent loaded in thymeleaf template

I've gone ahead and tried almost any tutorial with the hopes it wouldfix this.
I'm new to spring boot.
So I have a spring boot web application setup, but css, jscript and any other static content won't be loaded in template. It's not a problem with the css or jscript as implementing them directly into the html file will make it work.
This (http://prntscr.com/lk6f6q) is how my project looks like. "test".js just includes a simple alert call.
Html: https://hastebin.com/ixejakiqev.xml
Pom: https://hastebin.com/vakinawuva.xml
What am I doing wrong? I'm trying to solve this since a week and nothing seems to work. Am I maybe missing a library?
Check the exact issue using network tab of the browser.
and also ensure that you have a class something like below to handle static resources.
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(
"/webjars/**",
"/img/**",
"/css/**",
"/js/**")
.addResourceLocations(
"classpath:/META-INF/resources/webjars/",
"classpath:/static/img/",
"classpath:/static/css/",
"classpath:/static/js/");
}
}
The security config did not allow unverified access to the static resources.

how to stop accessing css and js from url in static folder ? Spring Boot

I just added all my css and js files in static folder and it could be easily accessed from url, how can I fix it? I added this method to my security configuration
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**");
}
but it doesn't work
Assuming for an example that you don't want to expose /static/that/ folder.
Rather than Blacklist approach I suggest selectively define a Whitelist of your resources like below (where you don't define say /static/that/)
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/this/,classpath:/public/ # Locations of static resources.
Excert of code above, taken from Spring Boot Documentation

spring - disable all caching for static content

how can I disable caching of the static content?
I tried to put this in my applications.properties:
spring.cache.type=NONE
This is my config:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/**")
.addResourceLocations("classpath:/static/")
.resourceChain(true).addResolver(
new VersionResourceResolver().addContentVersionStrategy("/**"));
}
Still when I change something in the css file I have to reload the page with the developer console opened in order for it to show.
Thanks!
Move all the resources out of classpath. To replace something loaded to classpath you may need something complex like own class loader etc. Try to move to a separate folder all the resources you need to change.

Unable to access the html file in template folder of spring boot application

html files are placed under resources/templates/login.html directory of spring boot application(show in the screenshot), deployed it in the weblogic server and when I try to access the login.html with the below URL, it gives The webpage cannot be found message
http://localhost:7001/demo/login.html
below is the screenshot
In one of the post I found the below code snippet and tried, but it didn't work
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
}
I am not getting what mistake I did, Could some one help me regarding this ...?
Spring Boot by default serves all content found under /static, /public, /resources or /META-INF/resources, see docs. So all content in your static folder should be served well (check that). But the templates folder is not a sub-folder of the static, so it will not be served. If I get you right, the templates is not supposed to be part of the URL path, right? So you could either move your login.html to the static folder, or you could add the templates folder to the classpath resource locations. Either programmatically (as you did for the other locations), or by setting the corresponding property:
spring.resources.static-locations=classpath:/templates/,classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/

Resources