Introduction to Spring web applications

In this tutorial, we are going to create simple web applications in Spring. Three web applications are created; each of the applications is configured in a different way. We will use NetBeans to build the application and the application is going to be deployed on Tomcat server.

Spring is a popular Java application framework. Spring Boot is an effort to create stand-alone, production-grade Spring based applications with minimal effort.

There are three basic approaches to configure a Spring web application:

Traditionally, Spring has used XML files to configure applications. Later, a new approach was created where the configuration is done in the Java configuration classes. Spring Boot autoconfiguration magic is the latest approach to configure Spring web applications.

Spring web application configuration with XML

In the first example, we create a Spring web application configured in XML files.

Spring web project structure in NetBeans
Figure: Spring web project structure in NetBeans

This is the project structure of the Spring web application using in NetBeans.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         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.zetcode</groupId>
    <artifactId>SpringFirstWebXmlEx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>SpringFirstWebXmlEx</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    <dependencies>
        
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>        
        
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>            
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.4.RELEASE</version>
        </dependency>        
        
    </dependencies>

</project>

This is the Maven build file. We use three dependencies: javaee-web-api, jstl, and spring-webmvc. The application is packaged into a WAR file, which is going to be deployed on Tomcat.

context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/SpringFirstWebXmlEx"/>

This is the context.xml file. It is used to uniquely identify the web application.

spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
   http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <context:component-scan base-package="com.zetcode" />
                
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
                  value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
</beans>

The spring-servlet.xml defines the beans for the servlet's app context. It contains configuration about the Spring web MVC.

<context:component-scan base-package="com.zetcode" />

This tells Spring where to look for classes with @Controller, @Repository, @Service, @Component annotations and register them. In our case, we have a controller with the @Controller annotation.

<bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass"
                value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>

Here we define a view resolver. Views in Spring are addressed by a view name and are resolved by a view resolver. UrlBasedViewResolver is a simple view resolver which simply resolves views by matching URL patterns to corresponding file names. In our case, views are JSP pages, which are located in the /WEB-INF/views/ subdirectory.

web.xml
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>      
    
    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>    
    
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>

In the web.xml file, we set up the Spring DispatcherServlet and choose the welcome file. The DispatcherServlet is the Spring's front controller. The servlet is mapped to the URL having *.html extension.

MyController.java
package com.zetcode.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MyController {

    @RequestMapping(value="/message", method=RequestMethod.GET)
    public String message() {
        return "showMessage";
    }    
}

HTTP requests are handled by a controller. It prepares a model and returns a view. The returned showMessage string is mapped to the showMessage.jsp file located in the /WEB-INF/views/ directory.

showMessage.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Message</title>
    </head>
    <body>
        <p>Today is a sunny day!</p>
    </body>
</html>

The showMessage.jsp file displays a message.

index.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Home page</title>
    </head>
    <body>
        <p>
            <a href="message.html">Show message</a>
        </p>
    </body>
</html>

The index.jsp is a home page. It contains a link.

Spring web application configuration with Java config

In the second example, we create a Spring web application configured in Java config classes. In this example, web.xml and spring-servlet.xml are replaced with MyWebInitializer.java and WebConfig.java.

Spring web project structure in NetBeans 2
Figure: Spring web project structure in NetBeans 2

This is the project structure of Spring web application using in NetBeans, configured with Java configuration classes.

context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/SpringFirstWebJavaConfigEx"/>

The second application has this context.xml file.

Excerpt from pom.xml
<dependencies>
    
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>        
    
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>            
    
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.3.4.RELEASE</version>
    </dependency>        
    
</dependencies>

The Maven build file contains the same three dependencies: javaee-web-api, jstl, and spring-webmvc. The application is packaged into a WAR file, which is going to be deployed on Tomcat.

WebConfig.java
package com.zetcode.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

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

    @Bean
    public ViewResolver viewResolver() {

        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setViewClass(JstlView.class);
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}

The WebConfig.java is used instead of the spring-servlet.xml file. We configure the view resolver.

MyWebInitializer.java
package com.zetcode.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyWebInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"*.html"};
    }
}

The MyWebInitializer class is used instead of the web.xml file. We utilize the WebConfig class and set up the URL mappings to *.html.

MyController.java
package com.zetcode.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MyController {

    @RequestMapping(value = "/message", method = RequestMethod.GET)
    public String message() {
        return "showMessage";
    }
}

This is the controller.

showMessage.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Message</title>
    </head>
    <body>
        <p>Today is a sunny day!</p>
    </body>
</html>

The showMessage.jsp file displays a message.

index.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Home page</title>
    </head>
    <body>
        <p>
            <a href="message.html">Show message</a>
        </p>
    </body>
</html>

The index.jsp is a home page. It contains a link.

Spring Boot web application

In the third example, we create a web application with Spring Boot.

application.properties
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    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.zetcode</groupId>
    <artifactId>SpringBootFirstWebEx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>SpringBootFirstWebEx</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>           
        
    </dependencies>    
</project>

This is the Maven build file. The spring-boot-starter-web is a starter POM for building web, including RESTful, applications using Spring MVC.

application.properties
spring.mvc.view.prefix: /WEB-INF/views/
spring.mvc.view.suffix: .jsp

The application.properties file contains various configuration settings of a Spring Boot application. The two properties set the prefix and suffix of the Spring MVC module.

Application.java
package com.zetcode.web;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder 
            application) {
        
        return application.sources(Application.class);
    }

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

The Application sets up the Spring Boot application. The SpringBootServletInitializer runs a Spring application from the traditional WAR deployment.

MyController.java
package com.zetcode.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MyController {
    
    @RequestMapping(name="/message",  method=RequestMethod.GET)
    public String message() {
        
        return "showMessage";
    }
}

This is the controller class for the Spring Boot web application. A controller is decorated with the @Controller annotation. The controller has one mapping. The mapping resolves to the showMessage.jsp, which is located in the WEB-INF/jsp directory.

showMessage.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Message</title>
    </head>
    <body>
        <p>Today is a sunny day!</p>
    </body>
</html>

The showMessage.jsp shows a simple message.

index.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Home page</title>
    </head>
    <body>
        <p>
            <a href="message.html">Show message</a>
        </p>
    </body>
</html>

The index.jsp is the home page of the application containing a link.

In this tutorial, we have created our first Spring Boot web application. You might also be interested in the related tutorials: Standalone Spring applications, FreeMarker tutorial, Java tutorial, Introduction to Play, Introduction to Spark, or Introduction to Stripes.