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

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?

Related

Spring boot server using jetty is not forwarding to index.html by default when running in eclipse since spring-boot-starter-parent 2.1.12-RELEASE

UPDATE:
This problem exists in jetty from 9.4.25.v20191220, i have set the version back to 9.4.24 it correctly serves. Whether this is a bug or change of configuration I don't know.
Maybe someone can help, i appreciate this is all configuration issues but I've only had this issue having upgrade spring-boot-starter-parent to 2.1.13-RELEASE from 2.1.10-RELEASE.
Using #SpringBootApplication and everything else default, except with the following WebMvcConfigurer (found in another post here)
#Configuration
public class WebApplicationConfiguration implements WebMvcConfigurer
{
#Override
public void addViewControllers(ViewControllerRegistry registry)
{
registry
.addViewController("/{spring:\\w+}")
.setViewName("forward:/");
registry
.addViewController("/**/{spring:\\w+}")
.setViewName("forward:/");
registry
.addViewController("/{spring:\\w+}/**{spring:?!(\\.js|\\.css|\\.svg)$}")
.setViewName("forward:/");
}
}
Using Jetty, and with an angular project present at \src\resources\public\ including a index.html in the public directory.
In the previous spring version I could navigate to localhost:8080 and it would direct automatically to localhost:8080/list this is setup up as the redirect within the angular project index file.
But now using 2.1.13 i have to explicitly go to localhost:8080/index.html which does work, redirects to /list and i can navigate the website, but if i refresh the page or if i went explicitly to :8080/list i get whitelabel error 500
I've tried:
1.
Adding various other view controller rules:
registry.addViewController("/").setViewName("forward:/index.html");
registry.addViewController("/").setViewName("forward:index.html");
registry.addViewController("/**").setViewName("forward:index.html");
... But I don't think these are the problem anyway.
2.
Viewed ResourceHandlerRegistry to see the default resource locations, so it should pick up my index.html file.
3.
Adding spring.resources.static-locations=classpath:/public/xxx/**
I then get by going to localhost:8080/xxx/ or localhost:8080/xxx/index.html whitelabel 404
I upgraded spring due to security vulnerabilities, so currently tempted to go back to 2.1.10 or 11, and pull only the dependency versions required to mitigate vulnerabilities. I'd just like to understand what is going wrong, and obviously don't enjoy being defeated.
Does anyone know if there is changelogs for versions of spring that would shed any light to what has changed? I guess it could be due to any number of dependent projects though.
So it turns out that whatever the issue was it is fixed in jetty 9.4.27.v20200227.
Spring Boot releases from 2.1.10 contained new Jetty version for each release, with now release currently using 9.4.27.
Using spring boot 2.1.13-RELEASE with 9.4.27.v20200227, returns forwarding to what is expected with localhost:8080 loading /list

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)

Spring boot addResourceHandlers not working on linux

In my spring boot application, I am adding resource handlers via the below method. Handler is added to the location on windows setup, however are not being done so when deployed on my linux machine.
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//linux
registry.addResourceHandler("/content/**").addResourceLocations("file:/app/content/").setCachePeriod(0);
//windows
//registry.addResourceHandler("/content/**").addResourceLocations("file:/D:\files\").setCachePeriod(0);
}
NOTE: The target folder on the linux machine has read write permissions as well. Also, have tried with file:// and file:///
Any other settings that I might be missing. Access to the files on http://myhost/content/file.jpg result in 404 on linux
Resolved. Issue was with the apache proxy conf.
Initially I was serving the static files via apache. Later was doing so from within the spring boot application.
However,
ProxyPassMatch ^/content !
this setting was still there the conf which was not forwarding the requests to the interceptor.

How to Access Spring Configuration Outside a JAR File

I am new with Spring Boot Development and currently can't move-on on the issue of how to load my spring application configuration outside the jar file.
My existing code looks like this
private ApplicationContext context;
public static void main(String[] args){
SpringApplication.run(SMPPEngine.c1ass);
new SMPPEngine();
}
public SMPPEngine(){
loadConfiguration();
process();
}
private void loadConfiguration(){
context = new ClassPatthlApplicationContext(”application-context.xm1”);
}
What I want to achieve is to have the jar file next to application-context.xml in one directory so that when there are configuration changes,I don't need to recompile my code just to reflect the changes on application-context.xml.
Based on what I've read on the internet, this is possible by using 'file://directory/application.xml' instead of classpath. But my problem on using the later is that when you place your jar and file to other location, I am required to do code change to reflect the new directory which does not solve the problem of getting away from code recompilation.
I hope I made my issue clear, and get an immediately response with you guys :)
Thanks in advance :)
There are many approaches to do this, standard, you can use spring file: prefix for accessing filesystem paths.
but with spring boot, you can specifiy it in application.properties with
spring.config.location propertiy, or you can add it in command line when run the spring boot jar file like
java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
But for your codes, actually you do not need to re-create the spring context from the configuration files, but you want get the context instance, you just need to inject it
#Autowired
private ApplicationContext context;
Another approach, if you have the infrastructure. Would be to use Spring Cloud Config. After your Boot application is configured to read from it, they can be modified at anytime without recompilation or restarting.

How to change the way Spring Boot serves static files?

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.

Resources