I have the following in my Spring Boot configuration:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.setOrder(Ordered.HIGHEST_PRECEDENCE)
.addResourceHandler("**/*.*")
.addResourceLocations("file:static/");
}
Since I'm creating a single page app I want this resource handler to deliver static files if the following is true:
- URL does not start with /api
- This resource handler contains a file that matches the path from the URL
If there are no matching file, the resource handler should not respond with 404 but let the call through to the controllers of the project.
In one of them I place my fallback to index.html annotation (again unless the URL starts with /api):
@GetMapping({"/**", "/"})
This last part works fine but the problem is that the resource handler returns a 404 if there are no matching files instead of letting the call through (I'm used to the middleware patterns of Node.js and Go) to the controllers. How can I achieve this? Can I create my own resource handler that acts more middleware like?
In Go with Echo for example you just need to enable HTML5 with a skipper function for /api:
func main() {
server := echo.New()
server.Use(middleware.Static("static"))
server.Use(middleware.StaticWithConfig(middleware.StaticConfig{
Root: "static",
HTML5: true,
Skipper: noHTML5IfAPICallSkipper,
}))
server.Logger.Fatal(server.Start(":1323"))
}
func noHTML5IfAPICallSkipper(context echo.Context) bool {
if strings.HasPrefix(context.Path(), "/api/") {
return true
}
return false
}
How to enable this single page app routing patterns in Spring Boot?
Oh, and by the way, it's crucial that the static files are served from disk rather than from a classpath or anything else that is packaged inside a jar. This service will run with Docker and it has to be possible to mount the files from outside the container.