I've found a very strange behavior in Spring Boot when trying to serve static files with spaces (or any other special chars, like accents) in file names.
I'm using Spring Boot 2.6.1 with Spring WebMVC and the following customization:
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/repo/**")
.addResourceLocations("file:///srv/intranet/repo/");
}
}
I have two files under /srv/intranet/repo
, named foo.txt
and foo bar.txt
(note the space in the second file name).
When I start my application, I can access the first file at http://localhost:8080/repo/foo.txt
. But I cannot access the second file (the one with the space in the file name) at http://localhost:8080/repo/foo bar.txt
(I get a 404 error).
BUT if I put the file foo bar.txt
under src/main/resources/static
, then I can acces the file at http://localhost:8080/foo bar.txt
.
You can probably troubleshoot by putting Spring web on TRACE level where it emits below information while serving the file.
logging.level.org.springframework.web.servlet=TRACE
Below are the logs
2021-12-07 14:24:24.544 TRACE 17200 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/files/SO 1.png", parameters={}, headers={masked} in DispatcherServlet 'dispatcherServlet'
2021-12-07 14:24:24.568 TRACE 17200 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to HandlerExecutionChain with [ResourceHttpRequestHandler [URL [file:D:/img/]]] and 3 interceptors
2021-12-07 14:24:24.580 TRACE 17200 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : Applying default cacheSeconds=-1
2021-12-07 14:24:24.626 TRACE 17200 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : No view rendering, null ModelAndView returned.
2021-12-07 14:24:24.626 DEBUG 17200 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK, headers={masked}
CodePudding user response:
I have found a workaround for this issue.
Just add the following in your Spring Boot configuration file application.properties
:
spring.mvc.pathmatch.matching-strategy: ant-path-matcher
I'm not really sure why this works. The documentation for this property states that ant-path-matcher
is the default value, so in theory this is redundant.