Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot images uploading and serving

I'm making new Spring Boot app and want to be able to store and serve images, I want images to be stored in applications directory:
enter image description here

this is what uploading looks like for now:

@PostMapping("/")
@ResponseBody
public String upload(@RequestPart String title, @RequestPart MultipartFile img) throws IOException{
    String imgName = img.getOriginalFilename();
    Post p = new Post();
    p.setTitle(title);
    p.setImageName(imgName);
    postService.add(p);
    File upl = new File("images/" + imgName);
    upl.createNewFile();
    FileOutputStream fout = new FileOutputStream(upl);
    fout.write(img.getBytes());
    fout.close();
    return "ok";
}

this is how I want to get images

<img th:src="@{'images/' + ${post.imageName}}"/>

for now I get 404 and when I want to view some images in directory I get

Fatal error reading PNG image file: Not a PNG file

how should I do it to make it work?

like image 588
Weras Adve Avatar asked Aug 12 '17 14:08

Weras Adve


People also ask

Where does spring boot store images?

Spring Boot Controller The uploadImage() method handles the image upload. It accepts a multipart/form-data POST request on image upload and saves the image on the local file system.

What is MultipartFile used for?

Interface MultipartFile. A representation of an uploaded file received in a multipart request. The file contents are either stored in memory or temporarily on disk. In either case, the user is responsible for copying file contents to a session-level or persistent store as and if desired.

How do you upload an image or file along with the post JSON data spring boot?

To pass the Json and Multipart in the POST method we need to mention our content type in the consume part. And we need to pass the given parameter as User and Multipart file. Here, make sure we can pass only String + file not POJO + file. Then convert the String to Json using ObjectMapper in Service layer.


3 Answers

To access image from your images folder,

enter image description here

You need to override addResourceHandlers method of WebMvcConfigurerAdapter class like this:

@Configuration
public class ResourceConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**").addResourceLocations("file:images/");
    }
}

After that you need add / before images in URL like this:

<img th:src="@{'/images/' + ${post.imageName}}"/>
like image 193
Ajit Soman Avatar answered Oct 22 '22 16:10

Ajit Soman


Per default your Spring Boot application serves static content - in your case images - found at following locations:

  • /static
  • /public
  • /resources
  • /META-INF/resources

So usually, static/images/ would perhaps be the place where Thymeleaf should expect the static images which have to be delivered for rendering. But since this place is about static content and since it is in general a bad idea to save uploaded (dynamic) content inside your application I would recommend to DON'T do that. Did you think about what happens if your application is redeployed or moved to another machine? Your would have to backup / move the images in a cumbersome way. There are better solutions, storing the upload content at a separate location outside your app (which could for example be configurable and also reused by multiple instances) or even use a database to store image data. That would also enable handling images in a transactional context (e.g. isolation & rollbacks).

But If you now want to still store it inside your app, your can extend the locations by adding places to search for (actually static content). Although the answer of Ajit and even the documentation still gives the advice to extend your own WebMvcConfigurerAdapter, I personally would tend to implement WebMvcConfigurer instead, because the former is deprecated.

In this case it should look like:

@Configuration
public class AdditionalResourceWebConfiguration implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(final ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**").addResourceLocations("file:images/");
    }
}
like image 32
Kevin Peters Avatar answered Oct 22 '22 16:10

Kevin Peters


You can store external files in a folder named /static in the same directory as your jar and spring will scan them by default. So if you have static/images/ you can reference your images with:

<img th:src="@{/images/img.ext}"/>

So you would want to use new File("/static/images/" + imgName);

like image 1
Scott Avatar answered Oct 22 '22 14:10

Scott