1. Introduction

In this tutorial, we’ll focus on a core concept in Spring MVC, Controllers.

2. Overview

Let’s start by taking a step back and examining the concept of the Front Controller in the typical Spring Model View Controller architecture.

At a very high level, the main responsibilities include:

  • intercepting incoming requests
  • converting the payload of the request to the internal structure of the data
  • sending the data to Model for further processing
  • getting processed data from the Model, and advancing that data to the View for rendering

Here’s a quick diagram for the high level flow in Spring MVC:


As we can see, the DispatcherServlet plays the role of the Front Controller in the architecture.

The diagram is applicable to both typical MVC controllers, as well as RESTful controllers, with some small differences (described below).

In the traditional approach, MVC applications aren’t service-oriented; therefore, there’s a View Resolver that renders final views based on data received from a Controller.

RESTful applications are designed to be service-oriented and return raw data (JSON/XML, typically). Since these applications don’t do any view rendering, there are no View Resolvers, and the Controller is generally expected to send data directly via the HTTP response.

Let’s start with the MVC0-style controllers.

3. Maven Dependencies

In order to work with Spring MVC in Spring Boot, we’ll deal with the Maven dependencies first:


To get the latest version of the library, have a look at spring-boot-starter-web on Maven Central.

4. Spring Boot Web Config

Now let’s look at how we can configure the Spring Boot. Since we added the thymeleaf dependency in the classpath, we won’t need to configure any @Beans for that:


In our WebConfig, we’ll need to add a bean for the Geeting object and the ObjectMapper in order to enable the default servlet:

    public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> enableDefaultServlet() {
        return factory -> factory.setRegisterDefaultServlet(true);

    public Greeting greeting() {
        Greeting greeting = new Greeting();
        greeting.setMessage("Hello World !!");
        return greeting;

    public ObjectMapper objectMapper() {
        return new ObjectMapper();

So, for example, if the Controller returns a view named “welcome”*,*** the view resolver will try to resolve a page called “welcome.html” in the templates folder. This is the default folder where thyeamleaf will search for views.

5. The MVC Controller

Now we’ll finally implement the MVC style controller.

Notice how we’re returning a ModelAndView object that contains a model map and a view object; both will be used by the View Resolver for data rendering:

@RequestMapping(value = "/test")
public class TestController {

    public ModelAndView getTestData() {
        ModelAndView mv = new ModelAndView();
        mv.getModel().put("data", "Welcome home man");

        return mv;

So what exactly did we set up here.

First, we created a controller called TestController and mapped it to the “/test” path. In the class, we created a method that returns a ModelAndView object, and is mapped to a GET request. Thus, any URL call ending with “test” will be routed by the DispatcherServlet to the getTestData method in the TestController.

And, of course, we’re returning the ModelAndView object with some model data for good measure.

The view object has a name set to “welcome“. As discussed above, the View Resolver will search for a page in the templates folder called “welcome.html“.

Below we can see the result of an example GET operation:


6. The REST Controller

The setup for a Spring RESTful application is the same as the one for the MVC application, with the only difference being that there are no View Resolvers or model map.

The API will generally return raw data back to the client, XML and JSON representations usually, so the DispatcherServlet bypasses the view resolvers and returns the data right in the HTTP response body.

Let’s have a look at a simple RESTful controller implementation:

public class RestController {

    @GetMapping(value = "/student/{studentId}")
    public Student getTestData(@PathVariable Integer studentId) {
        Student student = new Student();

        return student;

We can see a quick snapshot of the output below:

Student Endpoint

The above output is a result of sending the GET request to the API with the student id of 1.

One quick note here is that the @RequestMapping annotation is one of those central annotations that we’ll really have to explore in order to use to its full potential.

7. Spring Boot and the @RestController Annotation

The @RestController annotation from Spring Boot is basically a quick shortcut that saves us from always having to define @ResponseBody.

Here’s the previous example controller using this new annotation:

public class RestAnnotatedController {
    @GetMapping(value = "/annotated/student/{studentId}")
    public Student getData(@PathVariable Integer studentId) {
        Student student = new Student();

        return student;

8. Conclusion

In this article, we explored the basics of using controllers in Spring Boot, both from the point of view of a typical MVC application, as well as a RESTful API.

As usual, all the code in the article is available over on GitHub.