Spring MVC : HelloWorld Application

Syed Hasan
6 min readFeb 11, 2020

--

Spring MVC (Java based Configuration)

In this tutorial I will demonstrate how to configure a HelloWorld application with Spring MVC Java Configuration. We will use Spring 5 dependencies, Maven for dependency management, JDK 11 (Amazon Corretto) and Tomcat 9 as runtime. I will try to explain every small thing in depth.

  1. Prerequisites
  • Download JDK 11 (Amazon Corretto): Download the one according to the OS you are using and your Processor architecture. Install it when download is completed.
  • Download Maven Binary as Zip file:
Maven Download Page
  • Download Tomcat 9 Binary as Zip file
Tomcat Download Page
  • Download Eclipse
Eclipse Download Page

Once the download has finished, select installation package for Java EE and install.

2. Brief discussion on Maven based project folder structure

Following is the structure of a Maven based project. in the root folder, there will be at least pom.xml (Project Object Model, which identifies the project as maven project) and src (Source directory). src directory will contain 2 directories (main, test). main will contain at least 2 (or 3 in some cases) directories (java, resources, webapp). java will contain our packages, resources mostly contains property files (in some cases, static resources such as css, js, images, html files). In Spring MVC project, webapp directory contains mainly JSP and static resources. However, if it is a Spring Boot project, static resources and HTML files are kept in resources directory.

Maven Project File Structure

3. Creating Project in Eclipse

  • Open Eclipse and go to File > New > Maven Project
New Maven Project Window

From the above window, check Create a simple project (skip archetype selection) and click on Next button.

  • In the following window, provide Group Id, Artifact Id and click Finish.
Maven Project Configuration Window

Now right click on the project, go to Properties > Project Facets. Put check mark in Dynamic Web Module and select 4.0, Check Java and select 11. At the right side, click on Runtimes and add your downloaded Tomcat 9 here. Click on Apply and Close.

Note that, we are avoiding xml based configuration and writing java based configuration which has become possible after Dynamic web module 3.1

Configuring Project Facets

4. Adding Dependencies

Open your pom.xml file. In <dependencies></dependencies> tag put the following dependencies.

<dependencies>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-webmvc</artifactId>        <version>5.2.2.RELEASE</version>    </dependency>    <dependency>        <groupId>javax.servlet</groupId>        <artifactId>javax.servlet-api</artifactId>        <version>4.0.1</version>        <scope>provided</scope>    </dependency>    <dependency>        <groupId>javax.servlet</groupId>        <artifactId>jstl</artifactId>        <version>1.2</version>    </dependency>    <dependency>        <groupId>javax.servlet.jsp</groupId>        <artifactId>javax.servlet.jsp-api</artifactId>        <version>2.3.3</version>        <scope>provided</scope>    </dependency></dependencies>

Above <dependencies></dependencies> tag we will include <packaging>war</packaging>, which means that we are creating web archive.

Below <dependencies></dependencies> put the following plugins.

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>

Since we are writing Java based configuration and not creating web.xml, hence <failOnMissingWebXml>false</failOnMissingWebXml> is important.

The full code for pom.xml will look like below.

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mainul35</groupId>
<artifactId>spring5-hello-world</artifactId>
<version>0.0.1-SNAPSHOT</version>

<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>

5. Writing configuration for Spring Application

Now let’s create a package in src > main > java folder. The package name will be com.spring5.practice.config. Let’s create a Class AppInitializer which will implement WebApplicationInitializer class provided by Spring. We will implement onStartup(ServletContext) method and the code for this implementation will be like below.

public class AppInitializer implements WebApplicationInitializer {

public void onStartup(ServletContext servletCxt) {

// ------------------ region RootContext creation and registration ----------------------
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(RootConfig.class);
rootContext.refresh();

servletCxt.addListener(new ContextLoaderListener(rootContext));
// ------------------- endregion RootContext creation and registration ----------------------

// ------------------ region ServletContext creation and registration ----------------------
AnnotationConfigWebApplicationContext servletRegisterer = new AnnotationConfigWebApplicationContext();
servletRegisterer.register(ServletConfig.class);
ServletRegistration.Dynamic registration = servletCxt.addServlet("servlet",
new DispatcherServlet(servletRegisterer));
// ------------------ endregion ServletContext creation and registration ----------------------

registration.setLoadOnStartup(1);
registration.addMapping("/");
}
}

In the above implementation we are doing 4 major things.

a) Defining and loading RootContext from RootConfig class (Which we will create a bit later).

b) Defining and loading ServletContext from ServletConfig class (Which we will create a bit later).

c) Telling the application that DispatcherServlet will load on application startup (Since, according to Spring’s concept, it will have only one Servlet, DispatcherServlet to receive and process all requests.)

d) Mapping DispatcherServlet with “/” meaning that any request coming at application root URL will be received by DispatcherServlet.

Alternatively, we could write the same configuration by extending AbstractAnnotationConfigDispatcherServletInitializer class. The code would look like below.

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return new
Class<?>[] {RootConfig.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return new
Class<?>[] {ServletConfig.class};
}

@Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new
String[] {"/"};
}
}
  • Writing RootConfig class for components scanning for dependency injection
// @ComponentScan(basePackages = {"com.spring5.practice.service"})
public class RootConfig { }

Note that currently we have no services and no package named with service, therefore our RootConfig class is empty and @ComponentScan is commented.

  • Writing ServletConfig class for Controllers scanning and template engine registration (for now)

Our ServletConfig class will implement WebMvcConfigurer interface. This interface provides many helpful default methods. One of which is configureViewResolvers(ViewResolverRegistry registry). We will override this method and introduce our jsp page folder locations (as prefix) and page extension (as suffix). We must annotate our class with @EnableWebMvc which will make sure that our class will be read as Web Mvc configuration class. The code is given below.

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {"com.spring5.practice.controllers"})
public class ServletConfig implements WebMvcConfigurer {

// Configuration to render VIEWS
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/views/", ".jsp");
}
}

We will create another package nammed com.spring5.practice.controllers and create our very first controller class there.

6. Creating a Controller class

@Controller
public class RootController {

@GetMapping("/")
public String helloWorld(Model model) {
model.addAttribute("name", "World");
return "hello";
}

@GetMapping("/say-hello")
public String helloName(Model model, @RequestParam(name = "name", defaultValue = "") String name) {
model.addAttribute("name", name.isBlank() ? "World" : name);
return "hello";
}
}

This is how our very first controller will look like. A controller method must be annotated with @Controller annotation. Its mapped methods must be annotated with a convenient mapping annotation [Learn more here].

7. Writing our jsp page

Now let’s create a hello.jsp page in webapp > WEB-INF > views directory. If there is no webapp directory, create it in src > main directory. In body tag of jsp page, put the following code.

<h1>Hello ${name}</h1>

The full code of JSP will look like below.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Hello world</title>
</head>
<body>
<h1>Hello ${name}</h1>
</body>
</html>

8. Running our application

Once we have done everything as per I have shown, let’s right click on our application > Run > Run on server and select the Tomcat server.

9. Checking if our program works

If the server finishes running our application successfully, eclipse embedded browser will render the root mapping of our application.

Index page rendered in Eclipse Embedded Browser

Let’s hit in the URL http://localhost:8080/spring5-hello-world/say-hello?name=Mainul. The following content will be rendered.

Running a project in Eclipse development environment adds the project name as context path. Therefore, after port, our application name is appended as root path.

Congratulations. Our very first Spring Hello World application worked successfully.

The complete source code will be found here.

--

--

Syed Hasan
Syed Hasan

Written by Syed Hasan

Software Engineer | Back-End Developer | Spring Developer | Cloud Enthusiast

No responses yet