How do I use Spring Boot to serve static content located in Dropbox folder?
I have a Spring Boot web application, and I would like to serve static content located in a shared Dropbox directory on my Linode VPS (~/Dropbox/images). I've read that Spring Boot will automatically serve static content from
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/",
but of course my Dropbox directory is not on the classpath.
Although I could configure Apache to serve the images in my Dropbox folder, I would like to take advantage of Spring Security to restrict access of the static content to authenticated users.
Solution 1:
You can add your own static resource handler (it overwrites the default), e.g.
@Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("file:/path/to/my/dropbox/");
}
}
There is some documentation about this in Spring Boot, but it's really just a vanilla Spring MVC feature.
Also since spring boot 1.2 (I think) you can simply set spring.resources.staticLocations
.
Solution 2:
Springboot (via Spring) now makes adding to existing resource handlers easy. See Dave Syers answer. To add to the existing static resource handlers, simply be sure to use a resource handler path that doesn't override existing paths.
The two "also" notes below are still valid.
. . .
[Edit: The approach below is no longer valid]
If you want to extend the default static resource handlers, then something like this seems to work:
@Configuration
@AutoConfigureAfter(DispatcherServletAutoConfiguration.class)
public class CustomWebMvcAutoConfig extends
WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String myExternalFilePath = "file:///C:/Temp/whatever/m/";
registry.addResourceHandler("/m/**").addResourceLocations(myExternalFilePath);
super.addResourceHandlers(registry);
}
}
The call to super.addResourceHandlers
sets up the default handlers.
Also:
- Note the trailing slash on the external file path. (Depends on your expectation for URL mappings).
- Consider reviewing the source code of WebMvcAutoConfigurationAdapter.
Solution 3:
Based on @Dave Syers answer I add the following class to my Spring Boot project:
@Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
private static final Logger LOG = LoggerFactory.getLogger(StaticResourceConfiguration.class);
@Value("${static.path}")
private String staticPath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if(staticPath != null) {
LOG.info("Serving static content from " + staticPath);
registry.addResourceHandler("/**").addResourceLocations("file:" + staticPath);
}
}
// see https://stackoverflow.com/questions/27381781/java-spring-boot-how-to-map-my-my-app-root-to-index-html
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("redirect:/index.html");
}
}
This allows me to start my spring boot app with the parameter --static.path
like
java -jar spring-app-1.0-SNAPSHOT.jar --static.path=/path/to/my/static-files/
This can be very handy for development and testing.
Solution 4:
There's a property spring.resources.staticLocations
that can be set in the application.properties
. Note that this will override the default locations. See org.springframework.boot.autoconfigure.web.ResourceProperties
.
Solution 5:
- OS: Win 10
- Spring Boot: 2.1.2
I wanted to serve static content from c:/images
Adding this property worked for me:
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:///C:/images/
I found the original value of the property in the Spring Boot Doc Appendix A
This will make c:/images/image.jpg to be accessible as http://localhost:8080/image.jpg