HTML Templates

We have used thymleaf as our templating engine instead of traditional jsps.

Home page

HTML




<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="ISO-8859-1">
  <title>Course Tracker</title>
 
  <link rel="stylesheet"
        href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
        integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
        crossorigin="anonymous">
 
</head>
<body>
 
<div class="container my-2">
  <h1>Courses List</h1>
 
  <a th:href = "@{/add}" class="btn btn-primary btn-sm mb-3"> Add Course </a>
 
  <table border="1" class = "table table-striped table-responsive-md">
    <thead>
    <tr>
      <th>
        <a th:href="@{'/page/' + ${currentPage} + '?sortField=courseName&sortDir=' + ${reverseSortDir}}">
          Course Name</a>
      </th>
      <th>
        <a th:href="@{'/page/' + ${currentPage} + '?sortField=instructor&sortDir=' + ${reverseSortDir}}">
          Course Instructor</a>
      </th>
      <th>
        <a th:href="@{'/page/' + ${currentPage} + '?sortField=email&sortDir=' + ${reverseSortDir}}">
          Course Email</a>
      </th>
      <th> Actions </th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="course : ${listCourses}">
      <td th:text="${course.courseName}"></td>
      <td th:text="${course.instructor}"></td>
      <td th:text="${course.email}"></td>
      <td> <a th:href="@{/update/{id}(id=${course.id})}" class="btn btn-primary">Update</a>
        <a th:href="@{/delete/{id}(id=${course.id})}" class="btn btn-danger">Delete</a>
      </td>
    </tr>
    </tbody>
  </table>
 
  <div th:if = "${totalPages > 1}">
    <div class = "row col-sm-10">
      <div class = "col-sm-5">
        Total Rows: [[${totalItems}]]
      </div>
      <div class = "col-sm-3">
                    <span th:each="i: ${#numbers.sequence(1, totalPages)}">
                        <a th:if="${currentPage != i}" th:href="@{'/page/' + ${i}+ '?sortField=' + ${sortField} + '&sortDir=' + ${sortDir}}">[[${i}]]</a>
                        <span th:unless="${currentPage != i}">[[${i}]]</span>     
                    </span>
      </div>
      <div class = "col-sm-1">
        <a th:if="${currentPage < totalPages}" th:href="@{'/page/' + ${currentPage + 1}+ '?sortField=' + ${sortField} + '&sortDir=' + ${sortDir}}">Next</a>
        <span th:unless="${currentPage < totalPages}">Next</span>
      </div>
 
      <div class="col-sm-1">
        <a th:if="${currentPage < totalPages}" th:href="@{'/page/' + ${totalPages}+ '?sortField=' + ${sortField} + '&sortDir=' + ${sortDir}}">Last</a>
        <span th:unless="${currentPage < totalPages}">Last</span>
      </div>
    </div>
  </div>
</div>
</body>
</html>


Add course page

HTML




<!DOCTYPE html>
<html lang="en" xmlns:th="http://thymeleaf.org">
<head>
    <meta charset="ISO-8859-1">
    <title>Course </title>
    <link rel="stylesheet"
          href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
          integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
          crossorigin="anonymous">
</head>
<body>
<div class="container">
    <h1>Course Tracker</h1>
    <hr>
    <h2>Save Course</h2>
 
    <form action="#" th:action="@{/save}" th:object="${course}"
          method="POST">
        <input type="text" th:field="*{courseName}"
               placeholder="Course Name" class="form-control mb-4 col-4">
 
        <input type="text" th:field="*{instructor}"
               placeholder="Instructor Name" class="form-control mb-4 col-4">
 
        <input type="text" th:field="*{email}"
               placeholder="Course Email" class="form-control mb-4 col-4">
 
        <button type="submit" class="btn btn-info col-2"> Save Course</button>
    </form>
 
    <hr>
 
    <a th:href = "@{/}"> Back to Course List</a>
</div>
</body>
</html>


Update course page

HTML




<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="ISO-8859-1">
    <title>Course Tracker</title>
 
    <link rel="stylesheet"
          href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    <h1>Course Tracker</h1>
    <hr>
    <h2>Update Course</h2>
 
    <form action="#" th:action="@{/save}" th:object="${course}"
          method="POST">
 
        <!-- Add hidden form field to handle update -->
        <input type="hidden" th:field="*{id}" />
        <input type="text" th:field="*{courseName}" class="form-control mb-4 col-4" placeholder="Course name">
        <input type="text" th:field="*{instructor}" class="form-control mb-4 col-4" placeholder="Course instructor">
        <input type="text" th:field="*{email}" class="form-control mb-4 col-4" placeholder="Email">
        <button type="submit" class="btn btn-info col-2"> Update Course</button>
    </form>
 
    <hr>
 
    <a th:href = "@{/}"> Back to Course List</a>
</div>
</body>
</html>


Spring MVC CRUD with Example

CRUD stands for Create, Read/Retrieve, Update, and Delete. These are the four basic operations to create any type of project. Spring MVC is a Web MVC Framework for building web applications. It is a spring module same as Spring boot, spring-security, etc. The term MVC stands for Model-View-Controller architecture. In this article, we will be building a simple course-tracking CRUD application that will be focused on the Spring MVC module.

Similar Reads

CRUD Example of Spring MVC

Project Structure...

1. Add Dependencies to build.gradle file

Add the following dependencies to build.gradle file if not already present....

2. Model Layer

Create a simple POJO (Plain old java object) with some JPA and Lombok annotations....

3. DAO (Data access object) / Repository Layer

...

4. Service Layer

@Repository: This annotation is a stereotype that marks the repository class. It indicates that the annotated class acts as a database on which CRUD operations can take place. JpaRepository : JpaRepository is a JPA-specific extension of the Repository. It contains the full API of CrudRepository and PagingAndSortingRepository. So it contains API for basic CRUD operations and also API for pagination and sorting. Here we enable database operations for Employees. To learn more about spring data Jpa, refer this article....

5. Controller Layer

...

HTML Templates

The service layer provides an abstraction over the data layer. Its main purpose is to fulfill business requirements. It is always better to separate business logic from app logic....

CRUD Operations

...

Contact Us