For some applications, MySQL just doesn’t fit the bill. That’s when you need a Spring Boot solution with MongoDB.

In fact, it’s very likely that MongoDB is the wave of the future. And the future is now.

Why? Because MongoDB facilitates rapid application development. Software developers with little-to-no experience in creating a fully normalized SQL database can quickly put together a document-focused persistent store using MongoDB.

That means they can start writing CRUD (create, read, update, delete) code much faster as well.

Fortunately, Spring Boot is a framework that makes it easy to access a MongoDB instance. In this article, we’ll go over how you can implement a Spring Boot solution with MongoDB.

As always, feel free to check out the code on GitHub.

 

The Use Case

Let’s say that your boss, Smithers, walks into your office one day and says he’d like you to grab a whole bunch of funny images for an upcoming web project.

And by “a whole bunch,” he means “hundreds.”

After Smithers leaves your office, you ask yourself: “Self, where am I going to get these images?”

Then it dawns on you: there are plenty of funny images on The Chive. You can grab some images from that site.

(In case you’re unfamiliar with TheChive, it’s a fun website that’s geared towards millennials — especially heterosexual dudes.)

You need a quick solution, so you decide to store links to the images in a MongoDB database. You set up your instance, find images on TheChive, and store their URLs in the database as documents.

(Yes, a lot was glossed over in that last paragraph, but this isn’t a MongoDB tutorial.)

Now, you need a web-based means to browse those images. Enter Spring Boot.

 

Set up the Dependencies

To get the ball rolling, go into Eclipse (or your IDE of choice) and start a new Maven project. Edit the POM file to include the following dependencies:

  <dependencies>
  	<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
  	<dependency>
  		<groupId>org.springframework.boot</groupId>
  		<artifactId>spring-boot-starter-web</artifactId>
  	</dependency>
  	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-thymeleaf</artifactId>
	</dependency>
	<dependency>
	    <groupId>org.springframework.data</groupId>
	    <artifactId>spring-data-jpa</artifactId>
	</dependency>
  </dependencies>

 

As you can see, many of the dependencies are standard fare. However, there’s one that stands out.

You’ve probably noticed it: spring-boot-starter-data-mongodb

As the name implies, that’s the dependency that enables your code to play nicely with a MongoDB instance.

 

Specify the MongoDB URL

As with any other type of database, a MongoDB instance lives somewhere. You’re going to have to tell Spring Boot where your instance is located.

You also need to specify a user name and password.

Fortunately, you can do all of that with the application.properties file. That line looks like this:

spring.data.mongodb.uri=mongodb://UserName:Password@YourHost:YourPort/chiveimages

Obviously, you’ll have to make some substitutions there. You’ll need to specify your own user name, password, host, and port.

Also, note the chiveimages part at the very end of the URL. That’s the name of your MongoDB database.

Once that’s done, save the properties file.

Keep in mind: that’s all the MongoDB configuration info you need to provide. The Spring framework will handle everything else.

 

Create The Entity Class

When designing software, it’s usually best to start at the bottom and work your way up. That’s why it’s a good idea to start the development work with the entity class.

In this case, call the class ChiveImage because that’s pretty intuitive.

But what fields do you put in the class? To answer that question, you need to look at a document in your collection.

Why? Because an instance of the ChiveImage class corresponds to a document in the MongoDB collection.

Just open up a mongo shell in your environment. Then, switch over to the database where you’re keeping the documents.

Remember, you called the database chiveimages (see the URL above). Switch to that database with the following command:

use chiveimages

Now, examine a single document in the collection where you’re keeping the image info. Let’s assume you named the collection images just to keep things agonizingly intuitive. Here’s how you would examine a single document in that collection:

db.images.findOne()

Issue that command and you should see something like the following:

documentfields

So you can see that there are 5 fields in the document: _id, image, category, date, and keys.

The _id field is the unique ID of the document.

The image field stores the URL of the image on TheChive.

The category field is a string that describes the category of the image itself. Since all of these documents reference (ostensibly) humorous images, the category is “Funny.”

The date field is the date that the document was put in the database. That’s helpful if you want to sort by most recent documents.

Finally the keys field is an array of tags. It’s not used here.

So let’s get back to answering the original question: what fields do you put in the ChiveImage class? You probably won’t be surprised to learn that you need one field for each of the 5 fields in the document.

Your ChiveImage class will look like this:

@Document(collection = "images")
public class ChiveImage {

    @Id
    public String id;

    public String image;
    public String category;
    public Date date;
    public List<String> keys;

    public ChiveImage() {}

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public List<String> getKeys() {
        return keys;
    }

    public void setKeys(List<String> keys) {
        this.keys = keys;
    }
}

 

Pay particular attention to that @Document annotation at the very beginning. That maps the class to a document within a collection. In this case, the document is in the images collection.

 

Define The Repository Interface

Thankfully, you can use the Repository pattern with Spring/MongoDB integration. If you’re already familiar with that pattern, this part should be a snap.

Here’s what your repository interface will look like.

public interface ImageRepository extends MongoRepository<ChiveImage, String> {

    List<ChiveImage> findTop10ByOrderByDateDesc();
    
}

 

As you can see, the interface extends the type-safe MongoRepository interface. That’s part of the framework so you don’t have to create it.

You’re specifying two types when you extend the interface: ChiveImage and String. ChiveImage is the class you want this repository to work with. String is the ID type.

Yes, the ID is in string format. It’s a (large) hexadecimal number.

To keep things simple, there’s only one method defined in the interface. It’s called findTop10ByOrderByDateDesc().

The method does exactly what it sounds like it does. It finds the first 10 documents ordered by date descending (meaning the most recently added documents are first).

That method also highlights a neat feature of Spring/JPA: you can literally just name a method like that and it will do exactly what the name “tells” it to do. You don’t have to specify a query.

So there you have it: an interface with a single method that will get the 10 most recent documents from the images collection.

 

Write the Controller

Next, it’s time to write the controller class that will use some of the other classes you’ve just created.

Create a controller called FunnyImagesController. Add code as follows:

@Controller
public class FunnyImagesController {
    
    @Autowired
    ImageRepository imageRepository;
    

    @RequestMapping("/funnyImages")
    public String viewFunnyImages(Model model) {
        //grab the top images
        List<ChiveImage> images = imageRepository.findTop10ByOrderByDateDesc();
                
        //put the list in the model
        model.addAttribute("images",images);
        
        //get out
        return "funnyImages";
    }
}

 

The code starts off by autowiring the ImageRepository that you created in the previous step.

Then, it maps the /funnyImages path to the funnyImages() method with the @RequestMapping annotation.

Next, the code retrieves a list of images by calling the findTop10ByOrderByDateDesc() method on the ImageRepository instance. That will give you a list of 10 ChiveImage objects, each packed with info about image links.

After that, the code plops the list of image objects into a model attribute appropriately named “images”.

Finally, the controller returns the string "funnyImages". That’s the HTML prefix name of the file to be returned when the user hits the /funnyImages path. The full name of the file is funnyImages.html.

On a Maven project that uses Spring Boot with Thymeleaf, the HTML templates usually go in src/main/resources/templates. That’s where the funnyImages.html file belongs.

htmllocation

 

Finally, Write the funnyImages.html Code

In the home stretch! Now it’s time to put code in the aforementioned funnyImages.html file.

Remember: you’re using Thymeleaf as your server-side template engine. So you’ll iterate through the images object you stored in the model using Thymeleaf syntax.

The relevant portion of the code looks like this:

                                <div th:each="image : ${images}" style="margin-bottom:30px">
                                    <img th:src="${image.image}"/>
                                </div>

 

If you’re already familiar with Thymeleaf, there’s nothing special going on there. It’s a simple iteration loop over the images attribute set in the controller.

During the loop, each item in the list is called image. Again, that’s intuitive.

Finally, the <img> tag spits out the relevant image. It does that by grabbing the value of the image field and putting that value in the src attribute of the tag.

You can think of that image.image syntax as image.getmage() in standard Java coding.

For readability purposes, it would probably be better if the image field was named imageUrl or url. Let’s call that a candidate for refactoring.

Anyhoo, that’s pretty much it on the front-end side. Now it’s time to test the whole thing out.

 

Testing It Out

Once you’re done with the coding, run the application. Within Eclipse, you can do that by right-clicking on the Application class, selecting “Run As…” and then selecting “Java Application” from the context menu that appears.

When the Spring Boot app has fully started, you can access your controller by going to the following link

http://localhost:8090/funnyImages

(It’s pretty standard around these parts to run Spring Boot applications on port 8090. If you’re using a different port, adjust the port value in the above URL accordingly.)

Assuming you’re pointing to a MongoDB instance with many documents that contain image URLs, you’ll see something like this:

chiveimage

 

That’s the first of 10 images (some of the ones that follow are NSFW).

 

Wrapping It Up

Now, you can tell Smithers that you’ve done exactly what he asked for. You’ve put together a web-browsable library of funny images.

Challenge: enhance the code by applying pagination so that users can see 10 images at a time and scroll back and forth through the entire image set.

Also, now that you now how to integrate MongoDB with Spring Boot, consider using MongoDB as your persistent store of choice over one of the SQL options. You might find that it’s worth the move.

Have fun!