Spring Boot + PostgreSQL + JSP CRUD

In this section, we will learn how to develop a basic Student Management Application using Spring Boot 3, Spring Data JPA, PostgreSQL, & JSP. The GitHub repository link is provided at the end of this tutorial. 

Note 

A quick side note here is that JSP has limitations on its own and even more so when combined with Spring Boot. So, we should consider the following template engines as better alternatives to JSP. 


Student List:


Add Student:


Update Student:



Tools and Technologies Used:

  • Spring Boot - 3.0.1
  • Java 17
  • Spring Framework - 6.0.3
  • Spring Data JPA - 3.0.1
  • Hibernate - 6.1.6.Final
  • Maven - 3.2+
  • PostgreSQL
  • JSP

Final Project Directory:



pom.xml

A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details utilized by Maven to build the 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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev.demo</groupId>
<artifactId>spring-boot-jsp-postgresql-crud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-jsp-postgresql-crud</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<!-- JSP -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- jstl for jsp -->
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

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

</project>


Configuring PostgreSQL Database and JSP View Resolver

First, you need to create a database in the PostgreSQL server. You can use the following command to create a database in the PostgresSQL server:
CREATE DATABASE students;

Now, let’s configure the Spring Boot application to use PostgreSQL as our data source. You can do that simply by adding PostgreSQL database URL, username, and password in the src/main/resources/application.properties file.

Open src/main/resources/application.properties file and add the following content to it:

spring.datasource.url=jdbc:postgresql://localhost:5432/students
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.show-sql=true

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update

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


Create the JPA Entity - Student.java

package com.knf.dev.demo.crudapp.model;

import jakarta.persistence.*;

@Entity
@Table
public class Student {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name="first_name")
private String firstName;

@Column(name="last_name")
private String lastName;

@Column(name="email_id")
private String emailId;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getEmailId() {
return emailId;
}

public void setEmailId(String emailId) {
this.emailId = emailId;
}
}


Spring Data JPA Repository Interface - StudentRepository.java

package com.knf.dev.demo.crudapp.repository;

import com.knf.dev.demo.crudapp.model.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;


@Repository
public interface StudentRepository extends JpaRepository<Student, Long>{

}


Create Student Service Interface - StudentService.java

package com.knf.dev.demo.crudapp.service;

import com.knf.dev.demo.crudapp.dto.StudentDTO;
import java.util.List;

public interface StudentService {

public void createOrUpdateStudent(StudentDTO empDTO);

public List<StudentDTO> getAllStudent();

public void deleteStudent(Long id);

public StudentDTO editStudent(Long id);

}


Create Student Service Implementation - StudentServiceImpl

package com.knf.dev.demo.crudapp.serviceImpl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import com.knf.dev.demo.crudapp.dto.StudentDTO;
import com.knf.dev.demo.crudapp.model.Student;
import com.knf.dev.demo.crudapp.repository.StudentRepository;
import com.knf.dev.demo.crudapp.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class StudentServiceImpl implements StudentService {

@Autowired
private StudentRepository studentRepository;

public void createOrUpdateStudent(StudentDTO studentDTO) {
Student student = convertDtoToModel(studentDTO);
studentRepository.save(student);
}

public List<StudentDTO> getAllStudent() {
List<Student> list = studentRepository.findAll();
List<StudentDTO> userList = list.stream()
.map(StudentDTO::new)
.collect(Collectors.toCollection(ArrayList::new));
return userList;
}

public void deleteStudent(Long id) {
studentRepository.deleteById(id);
}

public StudentDTO editStudent(Long id) {
Student student = studentRepository.getReferenceById(id);
return convertModelToDTO(student);
}

private Student convertDtoToModel(StudentDTO userDto) {
Student student = new Student();
if (userDto.getId() != null) {
student.setId(userDto.getId());
}
student.setEmailId(userDto.getEmailId());
student.setFirstName(userDto.getFirstName());
student.setLastName(userDto.getLastName());
return student;
}

private StudentDTO convertModelToDTO(Student student) {
StudentDTO studentDTO = new StudentDTO();
studentDTO.setId(student.getId());
studentDTO.setEmailId(student.getEmailId());
studentDTO.setFirstName(student.getFirstName());
studentDTO.setLastName(student.getLastName());
return studentDTO;
}
}


Create Student DTO - StudentDTO.java

package com.knf.dev.demo.crudapp.dto;

import com.knf.dev.demo.crudapp.model.Student;

public class StudentDTO {

private Long id;
private String firstName;
private String lastName;
private String emailId;

public StudentDTO() {
}

public StudentDTO(Student employee) {
this.firstName = employee.getFirstName();
this.lastName = employee.getLastName();
this.emailId = employee.getEmailId();
this.id = employee.getId();
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getEmailId() {
return emailId;
}

public void setEmailId(String emailId) {
this.emailId = emailId;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}
}


Create Student Controller - StudentController.java

package com.knf.dev.demo.crudapp.controller;

import java.util.List;
import java.util.Map;
import com.knf.dev.demo.crudapp.dto.StudentDTO;
import com.knf.dev.demo.crudapp.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class StudentController {

@Autowired
private StudentService studentService;

@GetMapping(value = {"/","/registration"})
public String registration(Map<String, Object> model) {
model.put("student", new StudentDTO());
return "student-add-update";
}

@PostMapping("/home")
public String createStudent
(@ModelAttribute("student") StudentDTO studentDto) {
studentService.createOrUpdateStudent(studentDto);
return "redirect:/list";
}

@GetMapping("/list")
public String listOfStudent(Model model) {
List<StudentDTO> studentList = studentService.getAllStudent();
model.addAttribute("studentList", studentList);
return "student-list";
}

@PostMapping("/delete")
public String deleteStudent(@RequestParam("id") String id) {
studentService.deleteStudent(Long.parseLong(id));
return "redirect:/list";
}

@GetMapping("/edit")
public String editStudent(
@RequestParam("id") String id, Map<String, Object> model) {
StudentDTO studentDTO = studentService
.editStudent(Long.parseLong(id));
model.put("student", studentDTO);
return "student-add-update";
}

}


View - student-add-update.jsp

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Student Management</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.4.1/css/all.css">
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
<script
src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.slim.min.js">

</script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js">
</script>
</head>
<body >
<div class="container my-5">
<h2>Student <c:out value="${student.id != null ? 'Update' : 'Registration' }" /></h2>
<div class="card">
<div class="card-body">
<div class="col-md-10">
<form:form method="POST" modelAttribute="student" action="/home" name="student">
<form:hidden path="id"/>

<div class="row">
<div class="form-group col-md-8">
<label for="name" class="col-form-label"> First Name
</label>
<form:input path="firstName" id="fname" class="form-control" />
</div>

<div class="form-group col-md-8">
<label for="name" class="col-form-label"> Last Name
</label>
<form:input path="lastName" id="lname" class="form-control"/>
</div>

<div class="form-group col-md-8">
<label for="email" class="col-form-label" > Email
</label>
<form:input path="emailId" id="emailId" class="form-control"/>
</div>
</div>

<div class="col-md-6">
<input type="submit" class="btn btn-success"
value="<c:out value="${student.id != null ? 'Update' : 'Register' }" />">&nbsp;&nbsp;
<a href="/list">Student List</a>&nbsp;
<c:if test="${student.id ne null}"><b>|</b>&nbsp;<a href="/registration">Registration</a></c:if>
</div>

</form:form>
</div>
</div>
</div>
</div>
</body>
</html>


View - student-list.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="stag" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Student Management</title>
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.4.1/css/all.css">
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
<script
src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.slim.min.js">
</script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js">
</script>
</head>
<body>

<div class="container my-2">
<div class="card">
<div class="card-body">
<p class="my-5">
<a href="/registration" class="btn btn-success">
Add User</a>
</p>
<div class="col-md-10">
<table class="table table-striped table-responsive-md">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email Id</th>
<th></th>
<th></th>
</tr>
<c:forEach items="${studentList}" var="student">
<tr>
<td>${student.firstName}</td>
<td>${student.lastName}</td>
<td>${student.emailId}</td>
<td>
<a class="btn btn-warning" href="/edit?id=${student.id}" >
Edit</a>
</td>
<td>
<form action="/delete?id=${student.id}" method="post">
<input class="btn btn-danger" type="submit" value="Delete" />
</form>
</td>
</tr>
</c:forEach>
</table>
</div>
</div>
</div>
</div>
</body>
</html>


Run the application - Application.java

package com.knf.dev.demo.crudapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

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

}

Application is the entry point that sets up the Spring Boot application. The @SpringBootApplication annotation enables auto-configuration and component scanning.

Let's run this Spring boot application from either IntelliJ IDEA IDE by right click - Run 'Application.main()'
Or you can use the below maven command to run:

mvn spring-boot:run
From the browser call the endpoint http://localhost:8080

Download Source Code

More related topics, 

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Spring Boot + Mockito simple application with 100% code coverage

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete