Spring MVC

Spring Pivotal Logo

Introduction to Spring MVC

  • A web framework built around the principles of Spring
  • POJO based and interface driven
  • Based on a Dispatcher Servlet / Front Controller pattern
  • Very lightweight and unobtrusive compared to other frameworks

Request / Response Life Cycle

  • Model
  • View
  • Controller

Vocabulary

  • DispatcherServlet - The entry / configuration point for the Application
  • Controller - Command pattern
  • RequestMapping - The url and request type that a method is tied to
  • ViewResolver - Used to locate JSP pages or whatever view we are using
  • Servlet-config - Configuration file per Dispatcher Servlet
  • POJO - Plain old Java Object
  • Bean - A Spring configured POJO

Dispatcher Servlet

Dispatcher servlet is what examines the incoming request URL and invokes the right corresponding controller method. It reads the web request URL and finds the appropriate controller method that can serve the web request and invokes it.

/src/main/webapp/WEB-INF/web.xml

Request Mapping

The process of mapping a web request to a specific controller method is called request mapping, and the dispatcher servlet is able to do this with the help of @RequestMapping annotation.

View Resolvers

View resolvers helps the dispatcher servlet identify the views that have to be rendered as the response for a specific web request. Spring MVC provides various view resolvers implementation to identify views, and InternalResourceViewResolvers is one such implementation.

@EnableWebMvc
@Configuration
public class ClientWebConfig implements WebMvcConfigurer {
 
   @Override
   public void addViewControllers(ViewControllerRegistry registry) {
      registry.addViewController("/index");
   }
 
   @Bean
   public ViewResolver viewResolver() {
      InternalResourceViewResolver bean = new InternalResourceViewResolver();
      bean.setViewClass(JstlView.class);
      bean.setPrefix("/WEB-INF/view/");
      bean.setSuffix(".jsp");
      return bean;
   }
}

Alternative way to configure using XML

<context:component-scan base-package="com.baeldung.web.controller" />
<mvc:annotation-driven />    
 
<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/" />
        <property name="suffix" value=".jsp" />
    </bean>
 
    <mvc:view-controller path="/" view-name="index" />
 
</beans>

Spring MVC Request Flow

Spring MVC Flow

  1. When we enter a URL in the browser, the request comes to the dispatcher servlet. The dispatcher servlet then acts as a centralized entry point to the web application.
  2. The dispatcher servlet determines a suitable controller that is capable of handling the request and dispatching this request to the controller.
  3. The controller method updates objects in the model and returns the logical view name and updated model to the dispatcher servlet.
  4. The dispatcher servlet consults with the view resolver to determine which view to render and passes the model data to that view.
  5. The view furnishes the dynamic values in the web page using the model data, renders the final web page, and returns this web page to the dispatcher servlet.
  6. At the end, the dispatcher servlet returns the final, rendered page as a response to the browser.

Web Application Architecture

  • Domain Layer - Representation of Data Storage required by Business Logic. It describes various domain entities, roles, attributes and relationship.
  • Persistence Layer - Repository to access domain objects. Responsible to make queries to data source to the data for CRUD operations.
    • @Repository annotation marks a specific class as a repository.
  • Service Layer - Service Layer exposes business operations.
    • @Service annotation marks a specific class as a service.

Controllers

Controllers are heart and soul of Spring MVC. Controllers handles all incoming request and building the response.

Responsibilities

  • Interpret user input and transform to input to a model
  • Provide access to business logic
  • Determines view based off of logic
  • Interprets Exceptions from the business logic / service tier
package hello;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class GreetingController {

    @GetMapping("/greeting")
    public String greeting(@RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
        model.addAttribute("name", name);
        return "greeting";
    }

}
  • Controllers are responsible for responding to User Actions.
  • Any Java Class can be converted to Controller by annotating by @Controller
  • Controller class is made up of request-mapped methods. @RequestMapping
  • Handler Mapping interface provides the abstraction for mapping request to handlers. DispatcherServlet dispatches the request to the handler methods based on the HandlerMapping.

Spring Web Annotations

@RequestMapping

  • method: compatible HTTP methods
  • params: filters requests based on presence, absence, or value of HTTP parameters
  • headers: filters requests based on presence, absence, or value of HTTP headers
  • consumes: which media types the method can consume in the HTTP request body
  • produces: which media types the method can produce in the HTTP response body
    @GetMapping("/transactions/{storeId}")
    public ResponseEntity<List<Transaction>> getTransactions(@PathVariable String storeId, @RequestParam("pickupDate") Optional<String> pickupDate) {
        logger.info("getTransactions; Get Transactions request for StoreId: {} and PickupDate: {}", storeId, pickupDate.orElse("EMPTY"));
        return new ResponseEntity<>(transactionService.getAllTransactions(storeId, pickupDate), HttpStatus.OK);
    }

@RequestBody

  • Body of Http Request to an Object
@PostMapping("/save")
void saveVehicle(@RequestBody Vehicle vehicle) {
    // ...
}

@PathVariable

@RequestMapping("/{id}")
Vehicle getVehicle(@PathVariable("id") long id) {
    // ...
}

@RequestParam

@RequestMapping
Vehicle getVehicleByParam(@RequestParam("id") long id) {
    // ...
}

@ExceptionHandler

With this annotation, we can declare a custom error handler method. Spring calls this method when a request handler method throws any of the specified exceptions.

@ControllerAdvice
public class TransactionExceptionHandler {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @ExceptionHandler({KnownException.class})
    public ResponseEntity handleKnownException(KnownException ex) {
        logger.error(ex.getMessage());
        return new ResponseEntity(ex.getStatus());
    }
}

Resources