Skip to content

2.4 Working with view controllers

Thus far, you’ve written three controllers for the Taco Cloud application. Although each controller serves a distinct purpose in the functionality of the application, they all pretty much adhere to the following programming model:

  • They’re all annotated with @Controller to indicate that they’re controller classes that should be automatically discovered by Spring component scanning and instantiated as beans in the Spring application context.
  • All but HomeController are annotated with @RequestMapping at the class level to define a baseline request pattern that the controller will handle.
  • They all have one or more methods that are annotated with @GetMapping or @PostMapping to provide specifics on which methods should handle which kinds of requests.

Most of the controllers you’ll write will follow that pattern. But when a controller is simple enough that it doesn’t populate a model or process input—as is the case with your HomeController—there’s another way that you can define the controller. Have a look at the next listing to see how you can declare a view controller—a controller that does nothing but forward the request to a view.

Listing 2.16 Declaring a view controller

java
package tacos.web;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

  @Override
  public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("home");
  }

}

The most significant thing to notice about WebConfig is that it implements the WebMvcConfigurer interface. WebMvcConfigurer defines several methods for configuring Spring MVC. Even though it’s an interface, it provides default implementations of all the methods, so you need to override only the methods you need. In this case, you override addViewControllers().

The addViewControllers() method is given a ViewControllerRegistry that you can use to register one or more view controllers. Here, you call addViewController() on the registry, passing in “/”, which is the path for which your view controller will handle GET requests. That method returns a ViewControllerRegistration object, on which you immediately call setViewName() to specify home as the view that a request for “/” should be forwarded to.

And just like that, you’ve been able to replace HomeController with a few lines in a configuration class. You can now delete HomeController, and the application should still behave as it did before. The only other change required is to revisit HomeControllerTest from chapter 1, removing the reference to HomeController from the @WebMvcTest annotation, so that the test class will compile without errors.

Here, you’ve created a new WebConfig configuration class to house the view controller declaration. But any configuration class can implement WebMvcConfigurer and override the addViewController method. For instance, you could have added the same view controller declaration to the bootstrap TacoCloudApplication class like this:

java
@SpringBootApplication
public class TacoCloudApplication implements WebMvcConfigurer {

  public static void main(String[] args) {
    SpringApplication.run(TacoCloudApplication.class, args);
  }

  @Override
  public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("home");
  }

}

By extending an existing configuration class, you can avoid creating a new configuration class, keeping your project artifact count down. But I prefer creating a new configuration class for each kind of configuration (web, data, security, and so on), keeping the application bootstrap configuration clean and simple.

Speaking of view controllers—and more generically, the views that controllers forward requests to—so far you’ve been using Thymeleaf for all of your views. I like Thymeleaf a lot, but maybe you prefer a different template model for your application views. Let’s have a look at Spring’s many supported view options.

Released under the MIT License.