Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

1. Overview

In this tutorial, we'll discuss how to upload and retrieve files using MongoDB and Spring Boot.

We'll use MongoDB BSON for small files and GridFS for the larger ones.

2. Maven Configuration

First, we'll add the spring-boot-starter-data-mongodb dependency to our pom.xml:


In addition, we'll need the spring-boot-starter-web and spring-boot-starter-thymeleaf dependencies to display the user interface of our application. These dependencies are also shown in our Guide to Spring Boot with Thymeleaf.

In this tutorial, we're using Spring Boot version 2.x.

3. Spring Boot Properties

Next, we'll configure the necessary Spring Boot properties.

Let's start with the MongoDB properties:


We'll also set the Servlet Multipart properties to allow uploading large files:


4. Uploading Small Files

Now, we'll discuss how to upload and retrieve small files (size < 16MB) using MongoDB BSON.

Here, we have a simple Document class — Photo. We'll store our image file in a BSON Binary:

@Document(collection = "photos")
public class Photo {
    private String id;
    private String title;
    private Binary image;

And we'll have a simple PhotoRepository:

public interface PhotoRepository extends MongoRepository<Photo, String> { }

Now, for the PhotoService, we'll have only two methods:

  • addPhoto() — to upload a Photo to MongoDB
  • getPhoto() — to retrieve a Photo with a given id
public class PhotoService {

    private PhotoRepository photoRepo;

    public String addPhoto(String title, MultipartFile file) throws IOException { 
        Photo photo = new Photo(title); 
          new Binary(BsonBinarySubType.BINARY, file.getBytes())); 
        photo = photoRepo.insert(photo); return photo.getId(); 

    public Photo getPhoto(String id) { 
        return photoRepo.findById(id).get(); 

5. Uploading Large Files

Now, we'll use GridFS to upload and retrieve large files.

First, we'll define a simple DTO – Video – to represent a large file:

public class Video {
    private String title;
    private InputStream stream;

Similar to the PhotoService, we'll have a VideoService with two methods — addVideo() and getVideo():

public class VideoService {

    private GridFsTemplate gridFsTemplate;

    private GridFsOperations operations;

    public String addVideo(String title, MultipartFile file) throws IOException { 
        DBObject metaData = new BasicDBObject(); 
        metaData.put("type", "video"); 
        metaData.put("title", title); 
        ObjectId id = gridFsTemplate.store(
          file.getInputStream(), file.getName(), file.getContentType(), metaData); 
        return id.toString(); 

    public Video getVideo(String id) throws IllegalStateException, IOException { 
        GridFSFile file = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(id))); 
        Video video = new Video(); 
        return video; 

For more details on using GridFS with Spring, check our GridFS in Spring Data MongoDB article.

6. Controllers

Now, let's take a look at the controllers — PhotoController and VideoController.

6.1. PhotoController

First, we have the PhotoController, which will use our PhotoService to add/get photos.

We'll define the addPhoto() method to upload and create a new Photo:

public String addPhoto(@RequestParam("title") String title, 
  @RequestParam("image") MultipartFile image, Model model) 
  throws IOException {
    String id = photoService.addPhoto(title, image);
    return "redirect:/photos/" + id;

We also have getPhoto() to retrieve a Photo with a given id:

public String getPhoto(@PathVariable String id, Model model) {
    Photo photo = photoService.getPhoto(id);
    model.addAttribute("title", photo.getTitle());
    return "photos";

Note that as we have the image data returned as a byte[], we'll convert it to a Base64 String to display it on the front-end.

6.2. VideoController

Next, let's have a look at our VideoController.

This will have a similar method, addVideo(), to upload a Video to our MongoDB:

public String addVideo(@RequestParam("title") String title, 
  @RequestParam("file") MultipartFile file, Model model) throws IOException {
    String id = videoService.addVideo(title, file);
    return "redirect:/videos/" + id;

And here we have getVideo() to retrieve a Video with a given id:

public String getVideo(@PathVariable String id, Model model) throws Exception {
    Video video = videoService.getVideo(id);
    model.addAttribute("title", video.getTitle());
    model.addAttribute("url", "/videos/stream/" + id);
    return "videos";

We can also add a streamVideo() method that will create a streaming URL from the Video InputStream:

public void streamVideo(@PathVariable String id, HttpServletResponse response) throws Exception {
    Video video = videoService.getVideo(id);
    FileCopyUtils.copy(video.getStream(), response.getOutputStream());        

7. Front-End

Finally, let's see our front-end.
Let's start with uploadPhoto.html, which provides a simple form to upload an image:

<h1>Upload new Photo</h1>
<form method="POST" action="/photos/add" enctype="multipart/form-data">
    Title:<input type="text" name="title" />
    Image:<input type="file" name="image" accept="image/*" />
    <input type="submit" value="Upload" />

Next, we'll add the photos.html view to display our photos:

    <h1>View Photo</h1>
    Title: <span th:text="${title}">name</span>
    <img alt="sample" th:src="*{'data:image/png;base64,'+image}" />

Similarly, we have the uploadVideo.html to upload a Video:

<h1>Upload new Video</h1>
<form method="POST" action="/videos/add" enctype="multipart/form-data">
    Title:<input type="text" name="title" />
    Video:<input type="file" name="file" accept="video/*" />
    <input type="submit" value="Upload" />

And videos.html to display videos:

    <h1>View Video</h1>
    Title: <span th:text="${title}">title</span>
    <video width="400" controls>
        <source th:src="${url}" />

8. Conclusion

In this article, we learned how to upload and retrieve files using MongoDB and Spring Boot. We used both BSON and GridFS to upload and retrieve files.

As always, the full source code is available in the GitHub project.

NoSql Bottom

Build a Dashboard Using Cassandra, Astra, and Stargate

Persistence bottom

Get started with Spring Data JPA through the reference Learn Spring Data JPA course:

Persistence footer banner
Inline Feedbacks
View all comments
Comments are closed on this article!