Introduction to Spring Controllers

Spring Controllers are the core concept of Spring MVC application.In this post, we will cover Spring MVC Controllers.

Introduction

Before we dive into the Spring controllers internals, let’s have a look at request workflow in Spring MVC application.

spring mvc

On a high level, Spring MVC workflow move around following points.

  1. Dispatcher Servlet intercepts all incoming requests.
  2. Converts payload of the request to Spring MVC data structure.
  3. Send a request to the specific controller for processing.
  4. Invoke business rule/ processing from the controller.
  5. Send a response to the view for rendering (using view resolver.)
  6. For RESTful controllers, send the response directly to customer skipping view resolver.

 

One of the central points in Spring MVC architecture is the DispatcherServlet which works as Front Controller. Our architecture diagram represents two different workflows.

  • Traditional Spring MVC applications, which send the response using view resolver based on the data sent by the controller.
  • RESTful application which returns raw data (JSON/ XML etc).This workflow does not involve any view rendering and the client will be responsible for the view.
  • In the above picture, for RESTful application, DispactherServlet is sending the response directly to the client without going through ViewResolver

 

1. Traditional Spring MVC Setup

Let’s start with the traditional Spring MVC application setup

1.1 Maven Dependencies

To add the required jar to our Spring MVC, application, we need to add spring-webmvc dependency using POM.xml file.

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.14.RELEASE</version>
</dependency>

 

1.2 DispatcherServlet

Before we start with our application, we need to configure DispatcherServlet for our application. DispatcherServlet is a Servlet which needs setup configuration.Java configuration based registration and initialization of the DispactherServlet is the recommended way.

public class CustomWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletCxt) {

        // Load Spring web application configuration
        AnnotationConfigWebApplicationContext applicationCtx = new AnnotationConfigWebApplicationContext();
        applicationCtx.register(ApplicationConfig.class);
        applicationCtx.refresh();
        servletCxt.addListener(new ContextLoaderListener(applicationCtx));
        
       // Create and register the DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(applicationCtx);
        ServletRegistration.Dynamic registration = servletCxt.addServlet("mvc", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/mvc/*");
    }
}

[pullquote align=”normal”]We need servlet-API 3.x.x for no XML based configuration [/pullquote]

If you like to configure your DispatcherServlet using the traditional web.xml, your web.xml will be similar to 

<web-app>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/app-context.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>/mvc/*</url-pattern>
    </servlet-mapping>
</web-app>

 

2. Spring Web MVC Configuration

To configure/ customize MVC components, Spring MVC provides an option to handle it either through Java Config or XML

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.javadevjournal"})
public class CustomWebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureDefaultServletHandling(
        DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver =new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/view/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}

Adding @EnableWebMvc will import the Spring MVC configuration from WebMvcConfigurationSupport.Above configuration in XML is equivalent to 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <context:component-scan base-package="com.javadevjournal" />    
    <mvc:annotation-driven/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/view/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
  </bean>
</beans>

[pullquote align=”normal”]If you are using Spring 5.x, WebMvcConfigurerAdapter class has been marked Deprecated. We can directly implement WebMvcConfigurer without the need for this adapter. [/pullquote]

 

3. Spring Controller

We have finished our infrastructure setup to build our controller.In the last part of this traditional application build up, we will create our Spring Controller with following features

  • The method will handle GET request.
  • It will store a welcome message in the model.
  • The controller will return a view which will display our welcome message.
@Controller
@RequestMapping("/greeting")
public class GreetingController {

    @GetMapping
    public String greeting(final Model model){
        model.addAttribute("message", "Welcome to our sample controller");
        return "greeting";
    }
}

Let’s try to understand different features of our MVC Controller

  • @Controller annotation registers our class as Controller with Spring.
  • @RequestMapping("/greeting") will ensure that our class will process any request mapped to /greeting URI.
  • Our greeting method is annotated with @GetMapping which means we will call this method when a GET request will be sent to /greeting URI.
  • Once greeting method is called, it is saving a message in the Model class and returning a view (in our example view name is “greeting”).
  • In our viewResolver, we configured following properties
    • prefix = <em>/WEB-INF/view/</em>
    • suffix = <em>.jsp</em>
  • ViewResolver will try to resolve view information sent from our controller by combining prefix and suffix configured in our application.
  • Final information about the view will be /WEB-INF/view/greeting.jsp.Spring will try to find greeting.jsp in the /WEB-INF/view/ which will display output on the front-end.

If you run your application, and open following URL on the browser http://localohost:port/mvc/greeting, you should be able to see “Welcome to our sample controller” message on your browser window.

 

4. Spring MVC Setup using Spring Boot

In the first section, we created our controller in Spring.There were numbers of steps which were required before started working on our controller.

  • We setup required dependencies using pom.xml.
  • Created our DispatcherServlet Configurations.
  • Performed required MVC configurations

It can become more complicated once we use different API’s in our application which involves

  • Setting up required dependencies correctly.
  • Making sure all configurations are correct and compatible.

To handle our these infrastructure tasks, Spring team has introduced Spring Boot framework.

 

4.1 Spring MVC Application using Spring Boot

Read our article Creating a Web Application with Spring Boot  

 

5. The REST Controller

Setting up RESTful application is like the normal Spring MVC application setup, however, there are few fundamental differences between RESTful application and Spring MVC application

  • RESTful API does not require view resolver as they will send the response directly to the client.
  • RESTful API send raw data(JSON, XML etc) to the client application.
  • We typically use @RestController annotation for our REST controller.
@RestController
public class GreetingController {

    @GetMapping(value = "/greeting")
    public String greeting(final Model model){
        model.addAttribute("message", "Welcome to our sample controller");
        return "greeting";
    }
}

Read Building Restful Web Services to get more understanding about REST controllers. 

 

Summary

In this post, we covered Spring Controllers. We discussed different options to create Spring MVC Controller.

Comments are closed.