How to change the way Spring Boot serves static files? - spring-boot

After using JHipster on a couple of new projects recently (Highly recommended ! Amazing work !), I am trying to back-port some of the concepts into an older webapp, essentially migrating it to Spring Boot and Angular.
In Spring Boot, the default location for static web resources (HTML, JS, CSS, etc.) is in a directory called public, static or resources located at the root of the classpath. Any of these directories will be picked up by spring boot and files in them will be accessible via HTTP.
In JHipster the web files are in the src/main/webapp directory. Which is the directory used by default in a classic Maven WAR project.
I like this better because :
it more clearly separates the static web stuff from the classpath resources used by the Java code
the nesting is less deep (we already have enough levels of directories nesting with Maven as it is!).
But if I just create webapp directory in my project and put my HTML files in it, they are not available via HTTP, and the build process creates the WEB-INF directory structure in it. I don't want that, and in JHipster this is not the case.
How can I configure Spring Boot to behave like it does in JHipster ?
For those not familiar with JHipster : How can I instruct Spring Boot to serve static files from a different folder, no included in the classpath ?

You can try following configuration. The idea should be pretty straight forward. It does register artifacts in assets directory.
public class AppMvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Including all static resources.
registry.addResourceHandler("/assets/**",
"/css/**",
"/img/**",
"/js/**"
).addResourceLocations("/assets/",
"/css/",
"/img/",
"/js/"
).resourceChain(true)
.addResolver(new PathResourceResolver());
super.addResourceHandlers(registry);
}
}

you can add following code in application.propertise:
spring.resources.static-locations=classpath:/webapp/
and following code in application.yaml:
resources:
static-locations: classpath:/webapp/

I recently had the same issue and simply did a text search for "robots.txt" within my jHipster generated files.
I added my new file to the assets array in angular.json and put my new file in the same location as robots.txt, which as stated earlier is webapps.

Related

How can I fix spring boot to serve my static files from ROOT after upgrade

Recently, I upgraded my spring boot version from 2.2.6 to 2.6.1. After the upgrade, the server no longer finds my files in ROOT. The static files are built from an angular project which is added to my ROOT.war file at build time and the war file is moved to my server.
On the server, my static files are located at tomcat/webapps/ROOT. Previously (before upgrading) my files were found here and there were no issues. Since the upgrade typing myurl.com returns 404 but will return if I type myurl.com/index.html. I've tried to set up the WebMvcConfigurer for example
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/**")
.addResourceLocations("/");
}
I added to my application.properties
spring.mvc.pathmatch.matching-strategy=ant-path-matcher
I also added server.servlet.register-default-servlet=true thinking it was the DefaultServlet removal that caused the issue but this didn't make any difference.
In the logs, I can see the ResourceHttpRequestHandler is mapped to [classpath[META-INF/resources], classpath[resources/], classpath[static/], classpath[public], ServletContext[/]]
The logs also indicate the Resource is not found.
I can move the files to webapps/ROOT/WEB-INF/classpath/static and they show up but I was hoping to avoid messing with the build process. Was there a change in the framework to disable root level static file serving or am I missing something?

Where should I place my Vaadin 10+ static files?

In Vaadin 10-14, where should I place my static files, such as CSS, JavaScript, and Polymer templates? How about static files such as images?
Also, how do I import these files in Vaadin? Is there a difference between Vaadin 14 with npm and Vaadin 10-13 with bower?
All paths are relative to the project root, e.g. where the pom.xml file is located in a Maven project.
JavaScript imported using #JsModule uses strict mode. Among other things, this means that global variables must be defined on the window object, window.x = ..., instead of just x = ....
Vaadin 14 with npm
Non-Spring Boot projects (war packaging)
CSS files
#CssImport("./my-styles/styles.css")[1]
/frontend/my-styles/styles.css
JavaScript and Polymer templates
#JsModule("./src/my-script.js")[1]
/frontend/src/my-script.js
Static files, e.g. images
new Image("img/flower.jpg", "A flower")
/src/main/webapp/img/flower.jpg
Spring Boot projects (jar packaging)
CSS files
#CssImport("./my-styles/styles.css")[1]
/frontend/my-styles/styles.css
JavaScript and Polymer templates
#JsModule("./src/my-script.js")[1]
/frontend/src/my-script.js
Static files, e.g. images
new Image("img/flower.jpg", "A flower")
/src/main/resources/META-INF/resources/img/flower.jpg
Add-ons (jar packaging)
CSS files
#CssImport("./my-styles/styles.css")[1]
/src/main/resources/META-INF/resources/frontend/my-styles/styles.css
JavaScript and Polymer templates
#JsModule("./src/my-script.js")[1]
/src/main/resources/META-INF/resources/frontend/src/my-script.js
Static files, e.g. images
new Image("img/flower.jpg", "A flower")
/src/main/resources/META-INF/resources/img/flower.jpg
Vaadin 10-13, Vaadin 14 in compatibility mode
Non-Spring Boot projects (war packaging)
CSS files
#StyleSheet("css/styles.css")[2]
/src/main/webapp/frontend/css/styles.css
Polymer templates, custom-style and dom-module styles
#HtmlImport("src/template.html")
/src/main/webapp/frontend/src/template.html
JavaScript
#JavaScript("js/script.js")[3]
/src/main/webapp/frontend/js/script.js
Static files, e.g. images
new Image("img/flower.jpg", "A flower")
/src/main/webapp/img/flower.jpg
Spring Boot projects and add-ons (jar packaging)
CSS files
#StyleSheet("css/styles.css")[2]
/src/main/resources/META-INF/resources/frontend/css/styles.css
Polymer templates, custom-style and dom-module styles
#HtmlImport("src/template.html")
/src/main/resources/META-INF/resources/frontend/src/template.html
JavaScript
#JavaScript("js/script.js")[3]
/src/main/resources/META-INF/resources/frontend/js/script.js
Static files, e.g. images
new Image("img/flower.jpg", "A flower")
/src/main/resources/META-INF/resources/img/flower.jpg
Footnotes
[1] The #JsModule and #CssImport annotations can also be used for importing from an npm package. In this case, the path is defined as #JsModule("#polymer/paper-input") or #CssImport("some-package/style.css"). Paths referring to the local frontend directory should be prefixed with ./
[2] The #StyleSheet annotation can also be used in Vaadin 14 with npm. The same paths as in V10-V13 can be used, including the context:// protocol #StyleSheet("context://style.css"), which resolves the path relative to the context path of the web application, like other static files. Styles included this way may cause issues with web components.
[3] The #JavaScript annotation can also be used in Vaadin 14 with npm. The V14 /frontend folder should then be used,.
#Tazavoo 's answer has been added to the official Vaadin documentation:
Vaadin Resource Cheat sheet
I just wanted to put it here because I hope this will stay updated in the future. Please forgive me that I don't post the tables here but this answer will run over otherwise.
While Erik Lumme's answer is basically correct, I would like to share my experience about java script loading in a vaadin23 spring boot project, packaged as war. There are subtle differences about how the path must be indicated.
#JsModule:
path prefixed by "./": The path must be relative to the "frontend" folder
path without prefix: The path must be relative to the "node_modules" folder (maintained by npm).
Loading a java script by Page.addJavaScript(): The path must be relative to the root of the deployed application (in tomcat), rsp. to "src/main/webapp" in the project source.
We have shared resources of several Vaadin 14 modules like this:
маke common directory form project root /resources/static
route request there via nginx at prod and via Spring at local dev
public class MvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("file:./resources/static/")
.setCachePeriod(3600);
registry.setOrder(Integer.MAX_VALUE);
}
for css remove all
#CssImport("./styles/root/global-styles.css")
and put in MainView (#Route view), see https://vaadin.com/docs/v14/flow/styling/importing-style-sheets:
#StyleSheet("/static/css/global-styles.css")
for images put it to css
.plus-btn {
background: url("../static/icons/plus.svg") no-repeat center;
}

How to integrate Sitemap.xml and Robot.txt files generated from free online source to Spring Boot Application

"I have Sitemap.xml and Robot.txt files generated from free online sources, and I want to integrate those with my Spring Boot Application" and want to access that as http://localhost:8080/Sitemap.xml.
Previously I work with Struts 2.x. where I usually drop those files in JSPs folder and I able to access that as http://localhost:8080/Sitemap.xml.
But here in Spring Boot Application, I am totally confused in adding them to Application. (My Doubts are listed Below).
In which folder I need to add these files?
2.Does it need any controller to access Sitemap.xml as http://localhost:8080/Sitemap.xml.
Help me in Sorting out this.
Thanks in Advance.
Added Sitemap.xml and Robot.txt under static folder, but no use of that.
you can add these files under public folder in src/main/resources.
For more info refer this.
Also, if you have security configuration then you need to modify as below:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/Sitemap.xml");
}

Thymeleaf +Spring Boot can't find files (FileNotFoundException)

This is a bit of a silly and frustrating one:
The #Configuration is taken from a tutorial website or forum and in it a
ServletContextTemplateResolver thymeleafTemplateResolver
is created using the ServletContext provided by spring boot.
When requested, a FileNotFoundException is thrown, despite the file being in the configured resources folder.
How do I get it to find the file / load it from the resources?
For thymeleaf to resolve the classpath resources, you need to configure a ClassLoaderTemplateResolver. (You were using a ServletContextTemplateResolver)
Also check that setPrefix is set to the correct folder, eg. "/thymeleaf/" if your documents are in resources/thymeleaf/ and that setSuffix is set to ".html" (or whatever your preferred file suffix is)
To also serve static content, you can extend WebMvcConfigurer and override addResourceHandlers, to then do e.g.
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
assuming a static folder in your resources.
(Spring controllers take precedence here)

Serving static contents in Spring Boot

I am developing a new poc for web application from Spring Boot. The packaging type of my application in war. In this all i want is to display some contents on a jsp. For that i have created a small jsp, and requierd css/images/js files i have put in resources/static folder. So my static folder contains css/images/js folders. I've added following code in my configuration file. My configuration extends from WebMvcConfigurerAdapter
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String[] pathPatterns = {"/components/**", "/images/**", "/scripts/**", "/styles/**"};
String[] resourceLocations = {"classpath:/static/components/", "classpath:/static/images/", "classpath:/static/scripts/, classpath:/static/styles/"};
registry.addResourceHandler(pathPatterns).addResourceLocations(resourceLocations);
}
However, my jsp does not get the reference of these file.
JSP Code
How to solve above problem..
Second concern, as per the spring boot reference documentation, it serves the static content which are located in static folder. that means i should be able to access files from my static folder directly in below way
http://localhost:8080/styles/main.css
But this is also not working
Third Issue - static contents are served by default servlet ..is this true that Default servlet in enabled by default in Spring Boot application
Please Help
Putting the static resources inside src/main/resources/static folder works for me without any addResourceHandlers configuration. For example, I have a css file at
src/main/resources/static/public/css/styles.css
which I refer from my JSP like this:
<link href="/public/css/styles.css" rel="stylesheet">
You should have put your JSPs inside src/main/webapp/WEB-INF, and set the packaging to war rather than jar, due to the limitations of having JSPs in Spring Boot.

Resources