Right now I have a simple Spring Boot application that serves static images that I have placed in resources/static/img
. This works just fine for displaying the actual content, but there are two things I'd like to fix:
I don't want any of these images to be bundled with the resulting .jar
file, and I know that placing these images in the resources
folder will do that.
Using my current setup, in order to see a new image on the webapp, I have to add it to the folder and restart it. I would instead like Spring to serve any static content that exists in a specific folder, so I can add images while the application is running and have them automatically served at localhost:8080/img/{image name}
.
I attempted to solve this by setting up a resource handler, but I'm not sure if this is any different than simply serving them from resources/static
. Unfortunately, I'm still struggling with getting this configured correctly, as I'm unable to see any images at all. Here's what I tried:
@Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/img/**").addResourceLocations("file:" + Application.IMAGE_DIR);
super.addResourceHandlers(registry);
}
}
And here is my Application configuration:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
static String IMAGE_DIR;
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws IOException {
SpringApplication.run(Application.class, args);
IMAGE_DIR = new File(".").getCanonicalPath() + "/img/";
}
}
Again, my goal is to set up a folder in the root of my project called img
which will store the images that I would like the webapp to serve on localhost:8080/img/{image name}
. If possible, I'd like to be able to add content to this folder while the application is running and have Spring automatically serve them without having to restart it.
Does anyone have any ideas? Thanks in advance.
the problem with your approach is that you set IMAGE_DIR
after spring boot application is ran and the constant IMAGE_DIR
is not initialized and is null
. Change it as follows:
public static void main(String[] args) throws IOException {
IMAGE_DIR = "/opt/img/";
SpringApplication.run(Application.class, args);
}
and remove all File(".").getCanonicalPath()
related stuff and it will work. Your approach will fit in your needs when you have new image in selected directory it can be served.
A good solution for serving dynamic content with spring boot is to link a static content directory to a symbolic link with no cache and after that, you just need to rebuild symlink every time you need to reload. So in your case:
@Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/img/**").addResourceLocations("file:/tmp/images/").setCacheControl(CacheControl.noCache());
super.addResourceHandlers(registry);
}
}
After that, you change your image directory like this:
Path link = Paths.get("/tmp/images"); //Symlink
Files.deleteIfExists(link);
Files.createSymbolicLink(link, Paths.get(your_new_images_directory));
The choice of symlink /tmp/images is personal, you can choose what you want. Pay attention, your application needs to have good administrator rights for symlink creation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With