Spring MVC Fast Tutorial: building a Spring MVC web application

How Spring MVC works

Spring MVC works just like most web frameworks (Ruby on Rails, Django, etc):

  • Based on the request URL, a method from a controller class is executed.
  • That controller method often uses a model class to retrieve or store data in a database.
  • A view is rendered and sent as response.

What are we going to build?

A page displaying a list of cars.

We will use our previous project project and add to it:

  • a domain class: Car
  • a model class (also called a service class): will generate a list of cars
  • a controller class: will get the car list from the service class
  • a view (JSP): will display the car list

Create a domain class

Create the Java package com.jeromejaglale.domain and add the class Car to it:

public class Car {
	private String name;
	private BigDecimal price;
	// getters and setters

Create a service class

Create the Java package com.jeromejaglale.service and add the class CarService to it:

public class CarService {
	private List<Car> carList = new LinkedList<Car>();
	CarService() {
		Car car1 = new Car();
		car1.setName("Mercedes SL");
		car1.setPrice(new BigDecimal(123400));
		Car car2 = new Car();
		car2.setName("BMW M6 Coupé");
		car2.setPrice(new BigDecimal(125000));
		Car car3 = new Car();
		car3.setName("Audi R8");
		car3.setPrice(new BigDecimal(136100));
	public List<Car> findAll() {
		return carList;

We hardcoded a list of cars to keep things simple. It would normally be retrieved from a database.

In the AppConfig class, add the service package to @ComponentScan:

@ComponentScan(basePackages = {"com.jeromejaglale.service", "com.jeromejaglale.controller"})
public class AppConfig {

This will make Spring scan the service package at startup, discover the class CarService and create a CarService object (because of the @Service). We will use that object in our controller class.

Create a controller class

Add the class CarController to the controller package:

public class CarController {
	private CarService carService;
	public void carList(Model model) {
		List<Car> carList = carService.findAll();
		model.addAttribute("carList", carList);
  • At startup, Spring scans the controller package (because it's declared in @ComponentScan in the AppConfig class) and discovers CarController.
  • Spring knows CarController is a controller because of the class annotation @Controller.
  • The method annotated with @RequestMapping(”/car/list”) will be called by Spring for the route /car/list.
  • The @Autowired field CarService will be initialized by Spring with the instance automatically created at startup.
  • The Model object is used to pass data to the JSP view.
  • Spring will look by default for a view based on the route: /car/list. More in the next section.

Create a JSP view

In the pom.xml file, under <dependencies>, add:

<!-- JSTL -->

This dependency is required to use the JSP standard tag libray.

In the AppConfig class, add a view resolver for JSPs:

public ViewResolver jspViewResolver() {
    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    return resolver;

At startup, because of @Bean, Spring automatically executes jspViewResolver() and stores the returned ViewResolver, which will be used by Spring when needed. How a view resolver works:

  • a controller returns a String, implicitly or explicitly. In our project, it's implicitly ”/car/list”.
  • a view resolver is automatically used by Spring to find a matching view. This view resolver will look for the file /WEB-INF/jsp/car/list.jsp.

Create the file /WEB-INF/jsp/car/list.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
	<c:forEach items="${carList}" var="car">
			${car.name}: $${car.price}
  • we use carList, previously initialized in the controller method to display the list of cars.

Test wether it's working


We've built a complete Spring MVC web application. We have:

  • a service (model) class: CarService
  • a controller class: CarController
  • a view (JSP): /car/list.jsp

The controller gets a list of cars from the service and pass it to the view for display.

The source code is available on GitHub.

Next: Display and process a form
Previous: Hello, World!
Up: Spring MVC Fast Tutorial


là il n'y a rien qui fonctionne
reprendre la création de WEB-INF/jsp/car/list.jsp car il en manque pas mal
Jun 5, 2015
No source code for the JSP view itself?
Jul 4, 2015
It will not work without the class Initializer which implements WebApplicationInitializer

Have you tested? Whether your ServletInitializer is solving this issue?
Jul 18, 2015
Added the missing JSP code. If there's any problem, you can look at the source code on GitHub: https://github.com/jeromejaglale/spring4-tutorial
Jerome Jaglale
Sep 4, 2015
where do we have to create the jsp file ??
Dec 10, 2015
Sudheer: in /WEB-INF/jsp/car
Jerome Jaglale
Dec 10, 2015
Sudheer: Create folder named WEB-INF in the src/main/webapp folder, if not already there.
Arun Sharma
May 11, 2016
Jun 5, 2016
I have this problem:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authorController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.blazej.service.AuthorsRepository com.blazej.controller.AuthorController.repo; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.blazej.service.AuthorsRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Jun 16, 2016
my page output looks like not fetching the data. What would be the problem here. need a suggestion.


${car.name}: $${car.price}
Sep 6, 2016
Kannan, try to add this at the beginning of the JSP:

<%@ page isELIgnored="false" %>
Jérôme Jaglale
Sep 7, 2016
merci pour vos tuto qui vont a l’essentiel.

taks you it's short and very helpful.
may Allah bless you :)
Nov 20, 2017