The two common ways developers can serve static files are by saving them in a database and using a file server.

Saving files in a database is considered a bad practice as it affects the performance of your application. On the other hand, the best way to serve files is by using a file server such as Cloudinary.

In this tutorial, you will learn how to upload and serve static files in Spring Boot using Cloudinry. This will be a full fledge application covering both the back end and the front end.


  • Knowledge of Java programming language.
  • Cloudinary account – Create a free account that provides you with 3 users and 25 monthly credits. The free account has a number of features that you can play with including uploading and transforming images.
  • Java development kit(JDK)8 and above.
  • IntelliJ community edition – development environment for the Java programming language.

Project setup

To create a new project, go to Spring initialzr and select Maven in the Project section, and also select Java in the Language section.

On the Spring Boot section, select 3.0 as the version, and on the Project Metadata section, enter the options as shown below.

  • Group – com.javawhizz
  • Artifact – fileServer
  • Package name – com.javawhizz.fileServer
  • Packaging – Jar
  • Java – 17

To add dependencies, press the ADD button and add the dependencies Spring Web, Lombok, and Thymeleaf. Your project should have the following structure.

project setup

To download the project, press the GENERATE button and a ZIP folder of the project will be downloaded on your computer. Unzip the project and import it into IntelliJ.

The following dependency adds Cloudinary API to your project. Copy and paste it into the pom.xml file.


Configure Cloudinary

To create a package to hold your configuration class, create a package named config under the package src/main/java/com/javawhizz/fileServer.

Create a file named under the config package and copy and paste the following code into the file.

package com.javawhizz.fileServer.config;

import com.cloudinary.Cloudinary;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

public class CloudinaryConfig {
    private final String CLOUD_NAME = "YOUR_CLOUD_NAME";
    private final String API_KEY = "YOUR_API_KEY";
    private final String API_SECRET = "YOUR_API_SECRET";
    public Cloudinary cloudinary(){
        Map<String, String> config = new HashMap<>();

        return new Cloudinary(config);

In this file, you have configured your Cloudinary account by defining a bean and specifying the cloud name, API key, and API secret.

Enter the fields cloud_name, api_key, and api_secret as specified when creating the account.

The bean definition will return a single instance every time you make a call to upload a file.

Create a File upload service

To create a package to hold the project service, create a package named service under the package src/main/java/com/javawhizz.

Create a file named and copy and paste the following code into the file.

package com.javawhizz.fileServer.service;

import org.springframework.web.multipart.MultipartFile;


public interface FileUpload {
    String uploadFile(MultipartFile multipartFile) throws IOException;

In this file, you have created an interface that defines the method to upload your file. Since you want the method to return the file URL to be displayed on a web page, you make the method accept the parameter MultipartFile and return a String.

When uploading files, it is common to get input output exceptions such as file not found and due to this reason add an IOException signature to the method.

In the next section, you will see how the method is implemented to upload the file and return the URL.

Implement the File upload service

Create a file named under the service package and copy and paste the following code into the file.

package com.javawhizz.fileServer.service;

import com.cloudinary.Cloudinary;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;
import java.util.UUID;

public class FileUploadImpl implements FileUpload{

    private final Cloudinary cloudinary;
    public String uploadFile(MultipartFile multipartFile) throws IOException {
        return cloudinary.uploader()
                        Map.of("public_id", UUID.randomUUID().toString()))

To upload a file, inject the Cloudinary that you configured and call the uploader() method inside the uploadFile() method.

Call the upload() method on the uploader() method and pass the arguments multipartFile.getBytes() and Map.of("public_id", UUID.randomUUID.toString()).

The first argument sets the contents of the file and the second argument sets a random unique name for the file.

Once the file has been saved to the cloud, you will get a Map response and calling the get() method on the Map and passing the argument url returns the URL of the file.

Call the toString() method on the get() method to get a string representation of the Object returned.

Create a File upload controller

To create a package to hold the file upload controller, create a package named controller under the package src/main/java/com/javawhizz.

Create a file named under the controller package and copy and paste the following code into the file.

package com.javawhizz.fileServer.controller;

import com.javawhizz.fileServer.service.FileUpload;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;


public class FileUploadController {

    private final FileUpload fileUpload;

    public String home(){
        return "home";

    public String uploadFile(@RequestParam("image")MultipartFile multipartFile,
                             Model model) throws IOException {
        String imageURL = fileUpload.uploadFile(multipartFile);
        return "gallery";

In this file, you have created a controller that will help you to load the form to submit a file and the page to display the file.

The first method home() is the default access point to the application and it returns a web page named home.html that contains the form. You will create this form later.

The second method uploadFile() creates the file on the cloud and returns a web page named gallery.html.

To create the file on the cloud, inject the FileUpload service into the class and call the uploadFile() method. Pass Multipartfile as the argument of the method and create a variable to hold the string returned.

Add the string returned to the Model using the addAttribute() method for Thymeleaf to display the image once it is created.

Create a form to upload the file

Create a file named home.html under the folder src/main/resources/templates and copy and paste the following code into the file.

<!DOCTYPE html>
<html lang="en" xmlns:th="">
    <meta charset="UTF-8">

<form action="#" th:action="@{/upload}" method="post" enctype="multipart/form-data">
    <input type="file" name="image" placeholder="upload file">
    <input type="submit" value="Submit">



In this file, you have created a form that makes a post request to /upload to create a file with the name image on Cloudinary.

Create a page to display the file

Create a file named gallery.html under folder src/main/resources/templates and copy and paste the following code into the file.

<!DOCTYPE html>
<html lang="en" xmlns:th="">
    <meta charset="UTF-8">
<body style="background-color: cadetblue">

<div style="text-align: center">
    <img style="height: 200px; width: 300px"
    th:src="@{${imageURL}}" alt="test image">


In this HTML file, you have created a page that displays the image created on Cloudinary using Thymeleaf.

Ensure the name of the image added to the model is the same as the name displayed by Thymeleaf. For example, in this case, the name imageURL is the same for both the model and Thymeleaf.

Run and test the application

To run the application press the run icon located on the top right side of IntelliJ as shown below.

Running the application

If your application starts without any errors, go to localhost:8080. Your browser should display the following page.

File upload form
Click the Choose File button and select an image on your computer to upload to Cloudinary. After choosing a file, the No file chosen section will be replaced by the name of your file. Click the Submit button to create the image.

If your image is created without any errors, it should be displayed on the browser.

Image display page


In this tutorial, you have learned how to upload and serve images in Spring Boot using Cloudinary. To achieve this you have implemented both the back end and the front end with the use of Thymeleaf to display an image.

You have uploaded one image in this tutorial. However, you can play around with the project to upload multiple files. You can also add transformations to the images with the help of the transformation features provided by Cloudinary.

If you are a visual learner, this article is also available on Youtube. The code for this tutorial is available on GitHub to help you compare your code.

Happy coding!

Categories: Spring Boot


Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *