I reconfigured NixMash Spring to serve up static web content from /resources/static rather than a separate /webapp project folder. Under /resources/static were css, js, fonts and img folders. After applying the appropriate changes to the Spring Boot Config classes everything worked when running the web app in the IDE and with Gradle BootRun, but when running the Fat Jar generated with Gradle BootRepackage all content in the /css folder threw a 404!
Let’s crack this case!
Spring Boot Configuration Changes
The important thing to know about serving static web content is that Spring Boot takes care of mapping the resource paths as you’ll find in the guide “Serving Static Web Content with Spring Boot.” No need to write an addResourceHandlers() method, for instance, because Spring Boot already does that in WebMvcAutoConfiguration.
There is no need to add any default static elements to your Spring Boot Security Configuration either. You’ll see below that we don’t need to include /css or /js in our Ignored Resources list. We can probably get rid of /webjars now that I’m thinking of it.
In a NixMash Spring Controller we test the requested url against known paths to generate an Unknown Resource Exception, so we replaced “static” with the individual “css|js|img|fonts” directories here.
I actually ended up removing a bunch of stuff by conforming to standard practices for Spring static content and after learning more about what Spring Boot does in the background. I removed an addResourceHandlers() for webjars as well as my entire ThymeleafConfig class since I didn’t need it anymore with Thymeleaf views now in /resources/templates instead of /webapp/views.
HTML pages are now a bit cleaner without requiring a “/static/” before /css and other resource locations.
Here’s the updated resources folder layout. Clean.
One other thing to mention in regards to Gradle. Since I explicitly define my Java Project Source Sets I made sure that /resources was included as Java source in build.gradle.
Finally, here’s the nixmashSpring.war file produced with Gradle BootRepackage, with /static containing a /css subfolder just as it should.
BUT THE /CSS FOLDER WAS STILL THROWING A 404!
If you recall, everything was working beautifully except when running the WAR file on the command line. Everything in the /css folder was throwing a 404. Needless-to-say, this was quite the mystery! What was unique about the WAR file? Or was there something about the generation of the WAR file with BootRepackage perhaps? The biggest point of confusion was that the /css folder could not be found, but the /img, /fonts and /js folders were working perfectly.
I read a Spring Boot issue on GitHub from 2014 about static content not displaying when the Site Context Path wasn’t at the “/” root. That caused me to start thinking about the characteristics of the WAR web application and that it ran through an Apache Proxy at port 8086. This Proxy Mod routing to the NixMash Spring WAR wasn’t the issue, but it was time to take a look at the NixMash Spring Apache Configuration file.
When you see it…
You’ll notice that /css/ (and /images/ which isn’t used in our app) by-passes the Proxy, so is at a physical location of /ubuntuland/sites/nixmashspring/css. THIS is where the Apache HTTP Server was looking for /css files, not in the WAR /static/css directory! Our story ends happily with /css content displaying correctly after the Alias was removed in the Apache Site Config file.
The moral of the story is that developers often have to think about multiple steps of the web server process to solve a mystery.