Saving Files to System in Spring Boot

Kshitij Bajracharya
5 min readJul 30, 2019

--

Photo by Mr Cup / Fabien Barral on Unsplash

In Part 1 of this series, we created a model to save our documents and exposed an api to add them. However, we saw that only the information about the file was saved on the database, but the actual file was never saved on the system. In this article, we will see how to actually save the file on our system.

Note: This is the second article of a three-part series. In this article, I’ll be use the model and api from part 1 and save the physical file on to the system. This article does not cover the security aspects. That will be covered in the part 3.

Articles in this series:

  1. Upload files in Spring Boot
  2. Saving Files to System in Spring Boot (this)

First of all, we need to define where in our system do we want to save the files we upload. We define this in application.properties.

We define a property document.upload-directory and set its value to doc-uploads. This will tell Spring to save all the uploaded files in this directory. If the directory doesn’t exist, it will create this directory in the root of the project. But notice the yellow underline in this property? If you hover over to the lightbulb, you’ll see a message that says ‘document.upload-directory’ is an unknown property. Since, this is a custom property (one that is not given by Spring, as the other properties for H2 database written above), we need to define this property.

Create a package com.example.secretfile.property and then inside it create a class DocumentStorageProperty. Annotate it with @ConfigurationProperties to denote this is our custom property. Define the prefix as document. Inside the class, add a field uploadDirectory. This should match with what we have defined in application.properties.

Again hovering over @ConfigurationProperties recommends us to add the spring-boot-configuration-processor to pom.xml. Click on it. The following dependency is then added.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

The yellow underlines are now all gone.

Next we go to the DocumentServiceImpl and add a constructor for it. This will define the path where our files are to stored, so that we can use it when uploading the files.

docStorageLocation will hold this value. Now all that is left to do is copying the MultipartFile on to our system when saving the document instance. Update the create method.

This is where we will use the hash that we defined in Part 1. docStorageLocation will give us the directory where we wish to save our file and hash will be the name of our file. We don’t want to save the original name of the file, nor do we want to save the file extension. All of that details are already stored in the database. So, it takes the full path including our new file name in targetLocation, then copies our file to this location.

Before we run our application, let’s look at what our folder structure looks like.

Notice there’s no doc-uploads directory. It will be created once we run the application.

Run this application, and then we get the following error.

The log says Consider defining a bean of type ‘com.example.secretfile.property.DocumentStorageProperty’ in your configuration. We already did that but Spring doesn’t seem to pick this configuration up. So, we need to add an @Component to our DocumentStorageProperty class, telling Spring to scan this class as well.

Run the application again, and now everything looks fine. Let’s upload our documents using Postman as we had done in Part 1. If you check the folder structure now, you’ll see the following:

doc-uploads has been created and there are now two files in it — the jpeg and csv files we uploaded. Their names have however been changed and we have no idea which is which. So, there you go. Now not only the information about the files are saved in the database, but the actual file is also saved on the system.

But this is far from secure. Hiding the original filename and giving it a random name without the extension cannot be considered as file security. Because anyone that has access to the directory doc-uploads can easily open the files in it and view it. So securing files will be the next step, which we’ll cover in the third and final article of this series. You can find the complete code in the link below:

--

--