How to upload files in server's disk using spring boot

As stated in the title, we are going to demonstrate how to upload files to the server's filesystem. Everything has some pros and cons. But It depends upon your requirement. Identify your need and choose the right way.

You may be interested to know --> How to upload files to the database

upload files to server's disk

Step 1. Set file upload size limit and upload path in the properties file

We will set the directory path here in the properties file so that we can change it further if required depending upon the system where your application is deployed.

# I hope you can set the database properties 
#......
spring.servlet.multipart.enabled
=true
spring.servlet.multipart.max-file-size=2MB
spring.servlet.multipart.max-request-size=2MB

file.upload.location=/home/lavkush/uploads/
#for windows users they write the path like the below line
#file.upload.location=C:/Users/username/uploadedfiles/

Here we set the property file.upload.location it is not predefined. You may take anything like myfile.upload.path no matter what you write but you must know what you are doing. This value is can be accessed with @Value annotation directly in any class whether it is a service, controller, or entity.

Step 2. HTML form

This is just for a web application but the other things we will learn in further steps are applicable to REST applications too.

<form method="post" action="/uploadFile" enctype="multipart/form-data">
   <!-- other inputs -->
   <input type="file" name="myfile" accept="image/*">
   <input type="submit" value="Upload">
</form>

Here, in the form tag  enctype="multipart/form-data" is must send the files and other textual data to the server, if you do not apply, the controller will reject with the exception MultipartException: Current request is not a multipart request. And in the input type file tag, accept="image/" tells that it will accept only image files, we can apply other checks like audio/*, video/*, etc., and whatever we required. Or remove the accept attribute to upload any file type. 

 

Step 3. Create Entity to Save File Metadata

Metadata means file name, file type, etc. or sometimes you may need to store directory hierarchy. Here we are uploading image files to notice the entity below.

@Getter
@Setter
@NoArgsConstructor
@Entity
public class ImageGallary {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String fileName;
    private String fileType;

    public ImageGallary(String fileName, String fileType) {
        this.fileName = fileName;
        this.fileType = fileType;
    }
}

 

Step 4. Create JPA repository for the entity save/retrieve operations

We just need to save and find all methods here, thanks to JPA which reduces our work, here is what we require only.

public interface ImageRepository  extends JpaRepository<ImageGallary,Long> {
//..... other methods
}

 

Step 5. Create the controller to listen to the requests

In the controller method, we will save the file in the upload location and the name and type of the file will be saved to the database so that we can access the file later. You may write these operations to the service layer, but for understanding the fact we just creating it simply in the controller. 

@Controller
public class RequestController {
    @Autowired
    private ImageRepository imageRepository;

    @Value("${file.upload.location}")
    private String uploadLocation;

    @PostMapping("/uploadFile")
    public String uploadFile(@RequestParam("myfile") MultipartFile myfile) throws IOException {
        if (!myfile.isEmpty() && isRepositoryExists()) {
            String filename = getUniqueFileName(myfile.getOriginalFilename());
            OutputStream outputStream  = new FileOutputStream(uploadLocation+filename);
            outputStream.write(myfile.getBytes());
            ImageGallary img = new ImageGallary(filename, myfile.getContentType());
            imageRepository.save(img);
        }
        return "redirect:/";
    }

 

Step 6. Create a method to check if the upload directory exists or not 

In step 5 we have used a method isRepositoryExists() this will check whether the upload location is present or not. If not present then it will create the directory with the upload path. The upload path must be accessible to the OS user. Here is the method, add this to the controller.

public boolean isRepositoryExists() {
 File file = new File(uploadLocation);
      if (!file.exists()) {
            if (file.mkdir()) {
                System.out.println("Directory is created!");
                return true;
            } else {
                System.out.println("Failed to create directory!");
                return false;
            }
       } else return true;
}

 

Step 7. Create a method to generate a unique filename

Since we are uploading the files to a directory/folder so every file must have a unique name otherwise if we move to have two files with the same name the second file will replace the first one. To prevent this we will concatenate the current timestamp to the filename and replace every space with an underscore ( _ ).

private String getUniqueFileName(String originalFilename) {
        String timestamp = new SimpleDateFormat("yyMMddHHmm").format(new Date());
        String filename = originalFilename.replace(" ","_");
        filename = timestamp+filename;
        return filename;
 }

 

Step 8.  To access the files with filename we need to add and configure a resource handler

To register the resource handler we need to implement WebMvcConfigurer interface. We will set the resource handler path "/storage/**" and let suppose we uploaded a file with the name abc.jpg then if we access the http://localhost:8080/storage/abc.jpg then it will return the image file ( if the file exists).

@Configuration
public class ResourceConfig implements WebMvcConfigurer {
    @Value("${file.upload.location}")
    String uploadLocation;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/storage/**")
                .addResourceLocations("file:" + uploadLocation);
    }
}

 

Step 9. To Display the files in the UI add the controller method

@GetMapping("/")
    public String home(Model model) {
        List<ImageGallary> images = imageRepository.findAll();
        model.addAttribute("images", images);
        return "index";
    }

 

Step 10. Html  part to write the image details with Thymeleaf 

<h2 class="text-success">Images displayed using Resource Handler</h2>
<div class="row">
    <div class="col-md-4" th:each="img:${images}">
        <div class="container">
            <p th:text="${img.fileName}"></p>
            <p th:text="${img.fileType}"></p>
             <img th:src="${'/storage/'+img.fileName}" style="max-height: 220px">
        </div>
    </div>
</div>

 

Output Screen

file upload example to server directory

 

Thanks for your time, I hope you understand well the above explanation.

And as always you can find the source code on GitHub

 


×