Building a Basic Web Application | Part-03
This post will enable experts as well as beginners with Spring Boot web application development to understand the concepts behind a web application. It will explain these concepts by walking the reader through the process of developing a web application that enables the submitting of comments to a scrum retrospective meeting. This web application will use an embedded database for persistence, Spring Data JPA for a model, Spring Thymeleaf for a view, and Spring Web MVC for controllers.
The following topics will be covered in this example:
- Using Spring Data JPA for persistence
- Using Thymeleaf for view
- Using Spring Web MVC with servlet 3.x for controller
- Using Spring Security for authentication and authorization
- Demonstrating Retro Board
Workflow of Spring Web MVC
Spring Web MVC is a web framework that is built using a central front controller in the form of a Java servlet known as DispatcherServlet
. This servlet is responsible for the orchestration of the underlying components required in order to process a request it receives from clients (in most cases from a browser).
Spring Web MVC makes use of the following programming components of its own to make the web framework flexible and able to support different workflows:
HandlerMapping
: This is used to map a request to a handler with a set of configurable pre-request and post-request interceptors. For example, acontroller
class with a@RequestMapping
annotation will be mapped to a corresponding HTTP request by theRequestMappingHandlerMapping
implementation ofHandlerMapping
.Controller
: This is used to implement handlers to a particular HTTP request, which will be responsible for coordinating the business logic and response generation. For example, an HTTPGET
request to the URL/index
can be mapped to the@GetMapping("/index")
handler method in acontroller
class.Model
: This is used to send dynamic data in the form of attributes toView
. Flash messages, lists of domain-specific objects, and so on can be sent using aModel
.ViewResolver
: This is used to resolve view names usually returned by acontroller
handler method and get the actualView
in order to return an HTTP response.View
: This is used to generate the final presentation to the end user. These views will contain the syntax that will useModel
attributes to render responses dynamically.View
technologies supported by Spring Web MVC include plain Java Server Pages (JSP) with JavaServer Pages Standard Tag Library (JSTL), Spring Thymeleaf, Apache Freemarker, and so on.
As an example, an HTTP GET
request to path /index
from a web browser will result in the following orchestration when the request reaches DispatcherServlet
:
Let’s understand the preceding diagram:
- The browser will initiate the HTTP GET request for the path /index using the HTTP protocol
- The HTTP GET request in the form of the HTTP protocol will be resolved and handed over to DispatcherServlet by the Web container (this is a required but transparent step)
- DispatcherServlet will use the available HandlerMapping implementations to find a Controller that contains a handler method matching the path /index and HTTP request method GET
- DispatcherServlet will invoke the handler method from the Controller and return the View name and Model data if there are any
- DispatcherServlet will use any configured View Resolver to find the view by name and retrieve it
- DispatcherServlet will use a model, if any are available, along with the resolved View to prepare the final view that will be rendered
- DispatcherServlet will hand over the rendered View to the web container, which will convert it to an HTTP response and send it to the browser
This complex orchestration will take place for each HTTP request in a Spring Web MVC Framework-based application.
Requirements for our web application
We will be creating a dashboard, which will allow team members to share comments during retrospective meetings. During software development, a team usually carries out scrum retrospective meetings to share their comments on a sprint (a software development period usually a week long). These comments can be positive (plus), improvement (delta), and appreciation (flower).
These comments will be used as feedback to make the team work more efficiently during the following sprints. Usually, this is done using a whiteboard with a table drawn that has columns for pluses, deltas, flowers, and multicolor sticky notes, where each comment from a team member will be placed in a sticky note and posted on the whiteboard under the corresponding column.
Finally, all the comments will be noted and action will be taken in coming sprints accordingly. But this is a tedious process, one that can use technology to simplify the task, making it easier for each member to share their comments on a Sprint easily.
To address this requirement, a web application can be developed that will allow multiple users to log in to the web application and post their respective comments and collaborate in real time.
The following use case diagram shows the requirement for the dashboard, which is nicknamed Retro Board:
The actor is a User of the Retro Board and is a team member who is involved in a sprint. It has the following use cases:
- Login: This is required to authenticate users so that each comment can be uniquely identified
- Post Comments: This is where a logged in user can post their comment under its respective type so that it will be recorded for later, and also collaborate with other users in real time
- View Comments: This is where a logged in user can view comments made by all users
All actions need authentication and authorization to distinguish users and relate the comments they make. All comments need to be saved based on the date when they were made and should be retrievable based on the date also.
Understanding the Java Persistence API (JPA)
- A query language to enable querying from relational database tables in order to retrieve Java objects
- A JPA Criteria API, which can be used to generate queries dynamically
- A set of metadata defined with XML Java annotations in order to successfully map relational database table columns to Java object fields
Understanding Spring Data JPA
The Spring Data JPA project is an abstraction over JPA which vastly simplifies the process of object/relation mapping, querying, and so on. The following are some of the features of Spring Data JPA:
- Reduces/eliminates unnecessary boilerplate code
- Ease of building repositories with Spring and JPA
- Support for type-and value-safe JPA queries
- Support for database-independent auditing
- Support for database-independent pagination, custom query execution, and so on
Using Spring Data JPA for persistence
In this section, readers will learn what JPA is, as well as how Spring Data JPA helps simplify the development of applications with database persistence.
JPA provides object/relation mapping capabilities to enable mapping between relational database tables and Java objects in order to ease persistence in Java applications. JPA consists of the following features:
- A query language to enable querying from relational database tables in order to retrieve Java objects
- A JPA Criteria API, which can be used to generate queries dynamically
- A set of metadata defined with XML Java annotations in order to successfully map relational database table columns to Java object fields
JPA is not an actual implementation of the preceding features but merely defines the specification. Third-party vendors can perform their own implementation that conforms to the specification. The most popular third-party implementations that support JPA are Hibernate and EclipseLink.
JPA 1.0 was released in 2006 as part of Java Community Process JSR 220. Its latest version is JPA 2.2, which was released in 2017. JPA has made persistence easier and standardized for developers while allowing transactions and data consistency. This has helped a lot, making JPA famous among developers.
The Spring Data JPA project is an abstraction over JPA which vastly simplifies the process of object/relation mapping, querying, and so on. The following are some of the features of Spring Data JPA:
- Reduces/eliminates unnecessary boilerplate code
- Ease of building repositories with Spring and JPA
- Support for type-and value-safe JPA queries
- Support for database-independent auditing
- Support for database-independent pagination, custom query execution, and so on
Spring Data JPA eases Create, Retrieve, Update, Delete (CRUD) operations by allowing the JpaRespository
interface, which extends from CrudRepository
. This hides the complexities of plain JPA implementations, which need to be implemented and tested by developers. Using Spring Data JPA could reduce the development time dramatically because of this.
Using Spring Data JPA for persistence
In this section, readers will learn what JPA is, as well as how Spring Data JPA helps simplify the development of applications with database persistence.
JPA provides object/relation mapping capabilities to enable mapping between relational database tables and Java objects in order to ease persistence in Java applications. JPA consists of the following features:
- A query language to enable querying from relational database tables in order to retrieve Java objects
- A JPA Criteria API, which can be used to generate queries dynamically
- A set of metadata defined with XML Java annotations in order to successfully map relational database table columns to Java object fields
JPA is not an actual implementation of the preceding features but merely defines the specification. Third-party vendors can perform their own implementation that conforms to the specification. The most popular third-party implementations that support JPA are Hibernate and EclipseLink.
JPA 1.0 was released in 2006 as part of Java Community Process JSR 220. Its latest version is JPA 2.2, which was released in 2017. JPA has made persistence easier and standardized for developers while allowing transactions and data consistency. This has helped a lot, making JPA famous among developers.
The Spring Data JPA project is an abstraction over JPA which vastly simplifies the process of object/relation mapping, querying, and so on. The following are some of the features of Spring Data JPA:
- Reduces/eliminates unnecessary boilerplate code
- Ease of building repositories with Spring and JPA
- Support for type-and value-safe JPA queries
- Support for database-independent auditing
- Support for database-independent pagination, custom query execution, and so on
Spring Data JPA eases Create, Retrieve, Update, Delete (CRUD) operations by allowing the JpaRespository
interface, which extends from CrudRepository
. This hides the complexities of plain JPA implementations, which need to be implemented and tested by developers. Using Spring Data JPA could reduce the development time dramatically because of this.
In upcoming chapters, JpaRepository
with default methods and custom methods will be used extensively to implement business logic and demonstrate how to write Spring Data JPA repositories and test them. The following sections will discuss how to use a domain model designed using a class diagram as a base to implement Spring Data JPA-based entities and repositories.
The domain model is the most important part of an application; some applications have run for years on end with multiple frontend technologies but without ever changing the existing domain model. A well-built domain model can easily support multiple business logic and can run an application on limited resources efficiently.
The following is the simple class diagram for this web application:
There are two main domain models and one enumeration, as shown in the preceding diagram. Those are as follows:
- Comment: This is the main domain model, which will store the actual comment, comment type, comment created date, comment create a user, and so on
- User: This is the domain model, which will store the username, password, and role of a registered user
- CommentType: This enumeration is to differentiate comments by type
Setting up dependencies and configuration
Initially, before implementing the domain model, the dependencies and configuration class need to be specified. The following Maven starter dependency and H2 database dependency need to be included: