Spring Boot Web application with JSP (Spring Boot + JSP)

In this article we will see How to add JSP support in a Spring Boot application, How to create a .war file in spring boot and How to add static resources(css, js) in Spring Boot.

We will use SpringBootServletInitializer" to run a SpringApplication from a traditional WAR deployment, it binds Servlet, Filter and beans from the application context to the server.

Project structure

Following is the project structure, indicating where to put jsp's and static resources like css and js files, this project structure shows standard way of creating a spring boot jsp project.



Dependencies (pom.xml)

In order to create a Spring Boot Web application with JSP support and .war packaging we have to add spring-boot-starter-tomcat and tomcat-embed-jasper in pom.xml, tomcat-embed-jasper is required to compile JSPs.

<packaging>war</packaging> is to be added to pom.xml to make it a .war file packaged project.
<?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>
	<packaging>war</packaging>
	<groupId>com.tb</groupId>
	<artifactId>tb-web-jsp</artifactId>
	<version>0.1.0</version>

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

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
			<scope>provided</scope>
		</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>
	</dependencies>

	<properties>
		<java.version>1.8</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Spring boot application launch class

SpringBootServletInitializer is used to run a SpringApplication from a traditional WAR deployment, it binds Servlet, Filter and ServletContextInitializer beans from the application context to the server.

/src/main/java/com/tb/java/App.java
package com.tb.java;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;

/**
 * @author nagesh.chauhan
 *
 */
@SpringBootApplication
@ComponentScan("com.tb.*")
public class App extends SpringBootServletInitializer {

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

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


Here, @SpringBootApplication does all the magic, a class having main() and annotated with @SpringBootApplication is called Spring boot application launch class.

This annotation is a shortcut of applying 3 annotations in one statement,

1) @SpringBootConfiguration : It simply means that annotated class is a configuration class and shall be scanned for further configurations and bean definitions.

2) @EnableAutoConfiguration : As the name suggest, this annotation is used to auto configure Spring Application Context, Auto-configuration is always applied after user-defined beans are registered. One can always manually exclude any auto-configuration using the spring.autoconfigure.exclude property in properties file as shown below:

@EnableAutoConfiguration(excludeName = {"multipartResolver","mbeanServer"})

3) @ComponentScan : Provides support parallel with Spring XML's element.

Controller class

HomeController is annotated with @Controller, telling spring that the class will handle incoming requests, @GetMapping({ "/", "/home" }) indicates that both "/home" and "/" request will be handled by this method, Model parameter is used to send data from Controller to JSP and "index" returned as a string is name of JSP.

/src/main/java/com/tb/controller/HomeController.java
package com.tb.controller;

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

@Controller
public class HomeController {

	@GetMapping({ "/", "/home" })
	private String home(Model model) {
		model.addAttribute("message", "Hello World !");
		return "index";
	}
}


Add JSPs and Static resources

This is a simple JSP, you may notice two static resources are added here "style.css" and "app.js", this is just to explain How to add static resources in a spring boot web application.

We have passed only relative path to these .js and .css file this is because, Spring Boot will automatically add static web resources located within any of the following directories:

/META-INF/resources/
/resources/
/static/
/public/


/src/main/webapp/WEB-INF/jsp/index.jsp
<!DOCTYPE html>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Spring Boot JSP Example</title>
<link href="/css/style.css" rel="stylesheet">
<script src="/js/app.js"></script>
</head>
<body>
	<h1>${message}</h1>
	<h2>Spring Boot JSP Example</h2>

</body>
</html>

/src/main/resources/static/css/style.css
html {
	display: table;
	width: 100%;
}

body {
	display: table-cell;
	text-align: center;
	vertical-align: middle;
}

/src/main/resources/static/js/app.js
(function(){
    console.log("Hello World!");
})();

Changes in application.properties

We have added "prefix" and "suffix" properties of spring.mvc.view, this will map jsp names passed in controller to fully qualified named respective to webapp folder.

/src/main/resources/application.properties
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp

logging.level.org.springframework=TRACE
logging.level.com=TRACE

Run and Test the application

Here we are all done with "Creating a spring boot application supporting JSPs", do a maven clean-install and you will find .war file created in target folder, this file can be used to deploy on external application server like tomcat.

While using IDE like Eclipse, we can also run the application from App.java using run as > Java Application and the application will start on default 8080 port.

If everything goes right you will see a JSP view as shown below on both http://localhost:8080/ and http://localhost:8080/home:



We are done will adding jsp support in a sprinig boot application and .war packaging with a spring boot project, in upcoming applications we will see "How to add Spring Security in Spring Boot web application" and more about Spring Boot and Spring Framework.

Download complete project code from: GitHub