Spring BOOT and JSP integration

logo spring

Jakarta Server Pages (JSP), previously known as Java Server Pages, is the dynamic web page standard technology proposed by Java. Today it can be considered a relic of the past, as we have had template engines, such as Thymeleaf, that offer better capabilities for years. Moreover, the current trend is to create JavaScript clients with frameworks like Angular or React, which interact with REST APIs.

>> Read this post in Spanish here <<

However, since I have a certain fondness for it, in this short tutorial I am going to create a Spring Boot application that displays a web page generated with JSP.

Let’s start by adding the spring-boot-starter-web starter to the pom:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>   
</dependency>

JSP requires the dependency for the tag-based language JSTL (Jakarta Standard Tag Library):

<dependency>
	<groupId>org.glassfish.web</groupId>
	<artifactId>jakarta.servlet.jsp.jstl</artifactId>
</dependency>

It also needs a compilation engine because each JSP file is transformed into a servlet (*) that will be compiled like any other class:

<dependency>
  <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-jasper</artifactId>
  <scope>provided</scope>
</dependency>

(*) Servlets are Java classes that handle HTTP requests and HTTP responses.

In the configuration file application.properties we define the prefix and suffix of the .jsp files. The former is the path where they are located inside the /src/main/webapp folder and the latter is the file extension.

spring.mvc.view.prefix= /WEB-INF/jsp/
spring.mvc.view.suffix= .jsp

The next class represents the application. It is annotated with @SpringBootApplication and contains a main method that executes it.

@SpringBootApplication
public class SpringBootJspApplication {

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

}

The infrastructure is ready. Now let’s write a special class called controller with methods that Spring will invoke to handle the URLs we want:

@Controller
public class CountriesController {

    @RequestMapping("/")
    public String list(Model model) {
        model.addAttribute("countriesList", buildCountriesList());
        return "countriesList";
    }

    private List<Country> buildCountriesList() {
        List<Country> countries = new ArrayList<>();

        countries.add(new Country("Mexico", 130497248));
        countries.add(new Country("Spain", 49067981));
        countries.add(new Country("Colombia", 46070146));

        return countries;
    }

There is a lot to explain. We annotate our controller class with @Controller. @RequestMapping indicates the URL that will be handled by the method marked with it. Since it is the root of the application (/), we could skip it. Optionally, we can define the type of request (HTTP verb: GET, POST, PUT…) the method can handle. If it isn’t specified, all of them will be handled.

@RequestMapping(method = RequestMethod.GET)
public String list(Model model) {

Even more concise: use an annotation with the same function as @RequestMapping, but already fixed for a certain HTTP method. These annotations are @GetMapping, @PostMapping, @PutMapping, @DeleteMapping y @PatchMapping.

@GetMapping
public String list(Model model) {

In the list method, we get the list of countries and make it accessible to the JSP page by adding it to the Spring MVC Model, an object that we receive as a parameter. The Model class is a container holding the data that the controller sends to the view.

Finally, list returns the name of the view. Spring wraps it with the values we set in spring.mvc.view.prefix and spring.mvc.view.suffix to get the relative path to the file within the application. In our example that path is /WEB-INF/jsp/countriesList.jsp.

In /src/main/webapp/WEB-INF/jsp/countriesList.jsp we write the following web page:

<%@ page contentType="text/html; charset=UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link rel="shortcut icon" type="image/png" href="/favicon.png">

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
          crossorigin="anonymous">

    <link rel="stylesheet" href="/styles.css">
    <title>Spring Boot + JSP</title>

</head>

<body>

   <div class="container">

      <div class="title">
        <h1>Countries</h1>
      </div>

      <c:choose>

            <c:when test="${not empty countriesList}">
    
                <ul>
                    <c:forEach var="item" items="${countriesList}">
                        <li>${item.name}:<fmt:formatNumber
                                value="${item.population}" /></li>
                    </c:forEach>
                </ul>
    
            </c:when>
            
            <c:otherwise>
                <b>NO DATA</b>
            </c:otherwise>
            
        </c:choose>
    </div>

    <footer class="footer">
      <div class="container">
        <p class="text-muted"><a href="https://danielme.com/spring/">danielme.com</a></p>
      </div>
    </footer>

</body>

</html>

It is a pretty typical web page with Bootstrap 5. The most interesting part is the highlighted snippet: it generates HTML code every time the JSP is executed and is programmed with JSTL tags. The code is self-explanatory and will be familiar to you if you know PHP. If countriesList, the data contained in the model, has any items, it iterates through it to display them in a list; if not, a message is shown.

Notice that we have linked files (CSS and favicon). Static resources, such as images, CSS, JavaScript, etc, are placed in the /src/main/resources/static folder. They are accessible from the root URL of the application. For example, /src/main/resources/static/favicon.png will be available at /favicon.ico.

We are now ready to run the project using its main method (SpringBootJspApplication#main) with, for example, a development environment like Eclipse or IntelliJ. Being a web application is not a problem: Spring Boot starts an embedded Tomcat server with our application deployed on it. Spring Boot is awesome 😎

We can access the application by pointing a browser to the Tomcat root URL on port 8080.

You can change these settings with the following properties:

server.servlet.context-path=/spring-boot-jsp-demo
server.port=9090

Source code

The sample project is available on GitHub.


Other posts in English

Spring Framework: event handling

Spring Framework: asynchronous methods with @Async, Future and TaskExecutor

Testing Spring Boot: Docker with Testcontainers and JUnit 5. MySQL and other images.

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.