JSP Servlet MVC Example with Database

In this blog post, we'll create a simple MVC (Model-View-Controller) web application using JSP, Servlet, and a database. This example will demonstrate how to create, read, update, and delete (CRUD) operations for a Todo management system using the MVC design pattern.

Model-View-Controller (MVC) Architecture


From the above diagram, here is the MVC flow:
1. The web browser sends an HTTP request to a controller (Servlet).
2. The controller (servlet) gets a model object with data from the database or other sources.
3. The controller(servlet) redirects to a web page (JSP) with model data.
4. Finally, the web page(JSP) will be displayed with model data on the browser.

Tools and Technologies Used

  • JSP 3.0.0
  • Servlet Jakarta API 6.1.0
  • JSTL 3.0.0
  • Apache Tomcat 10.0
  • MySQL 8.0
  • Eclipse IDE

Development Steps

  1. Create an Eclipse Dynamic Web Project
  2. Add Dependencies
  3. Project Structure
  4. MySQL Database Setup
  5. Create JavaBean - Todo.java
  6. Create DAO - TodoDao.java
  7. Create Servlet - TodoServlet.java
  8. Create JSP Pages
  9. Demo

Step 1: Create an Eclipse Dynamic Web Project

To create a new dynamic web project in Eclipse:

  1. On the main menu, select File > New > Project....
  2. In the upcoming wizard, choose Web > Dynamic Web Project.
  3. Click Next.
  4. Enter the project name as "jsp-servlet-mvc-todo-example".
  5. Make sure that the target runtime is set to Apache Tomcat with the currently supported version.

Step 2: Add Dependencies

Add the latest release of the below JAR files to the lib folder:

  • jakarta.servlet-api-6.1.0.jar
  • mysql-connector-java-8.0.13.jar
  • jakarta.servlet.jsp.jstl-api-3.0.0.jar

If you are using a Maven project, then add the following dependencies to your pom.xml:

<dependencies>
    <dependency>
        <groupId>jakarta.servlet</groupId>
        <artifactId>jakarta.servlet-api</artifactId>
        <version>6.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>jakarta.servlet.jsp.jstl</groupId>
        <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
        <version>3.0.0</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.28</version>
    </dependency>
</dependencies>

Step 3: Project Structure

Here is the standard project structure for your reference:

jsp-servlet-mvc-todo-example
├── src/main/java
│   └── com/example/mvc
│       ├── model
│       │   └── Todo.java
│       ├── dao
│       │   └── TodoDao.java
│       └── controller
│           └── TodoServlet.java
├── src/main/webapp
│   ├── WEB-INF
│   │   └── web.xml
│   ├── index.jsp
│   ├── todo-form.jsp
│   └── todo-list.jsp
└── pom.xml

Step 4: MySQL Database Setup

Let's create a database named mvc_database in MySQL. Now, create a todos table using the following DDL script:

CREATE DATABASE mvc_database;

USE mvc_database;

CREATE TABLE todos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    description VARCHAR(255),
    is_completed BOOLEAN DEFAULT FALSE
);

Step 5: Create JavaBean - Todo.java

Create a Todo JavaBean class in the model package, which will be used in JSP action tags.

package com.example.mvc.model;

import java.io.Serializable;

public class Todo implements Serializable {
    private static final long serialVersionUID = 1L;
    private int id;
    private String title;
    private String description;
    private boolean isCompleted;

    // Getters and setters
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public boolean isCompleted() {
        return isCompleted;
    }
    public void setCompleted(boolean isCompleted) {
        this.isCompleted = isCompleted;
    }
}

Step 6: Create DAO - TodoDao.java

Create a TodoDao class in the dao package, which contains JDBC code to connect with the MySQL database and perform CRUD operations.

package com.example.mvc.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.example.mvc.model.Todo;

public class TodoDao {

    private String jdbcURL = "jdbc:mysql://localhost:3306/mvc_database?useSSL=false";
    private String jdbcUsername = "root";
    private String jdbcPassword = "root";
    private Connection jdbcConnection;

    protected void connect() throws SQLException {
        if (jdbcConnection == null || jdbcConnection.isClosed()) {
            try {
                Class.forName("com.mysql.cj.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                throw new SQLException(e);
            }
            jdbcConnection = DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);
        }
    }

    protected void disconnect() throws SQLException {
        if (jdbcConnection != null && !jdbcConnection.isClosed()) {
            jdbcConnection.close();
        }
    }

    public boolean insertTodo(Todo todo) throws SQLException {
        String sql = "INSERT INTO todos (title, description, is_completed) VALUES (?, ?, ?)";
        connect();

        PreparedStatement statement = jdbcConnection.prepareStatement(sql);
        statement.setString(1, todo.getTitle());
        statement.setString(2, todo.getDescription());
        statement.setBoolean(3, todo.isCompleted());

        boolean rowInserted = statement.executeUpdate() > 0;
        statement.close();
        disconnect();
        return rowInserted;
    }

    public List<Todo> listAllTodos() throws SQLException {
        List<Todo> listTodo = new ArrayList<>();

        String sql = "SELECT * FROM todos";

        connect();

        PreparedStatement statement = jdbcConnection.prepareStatement(sql);
        ResultSet resultSet = statement.executeQuery(sql);

        while (resultSet.next()) {
            int id = resultSet.getInt("id");
            String title = resultSet.getString("title");
            String description = resultSet.getString("description");
            boolean isCompleted = resultSet.getBoolean("is_completed");

            Todo todo = new Todo();
            todo.setId(id);
            todo.setTitle(title);
            todo.setDescription(description);
            todo.setCompleted(isCompleted);

            listTodo.add(todo);
        }

        resultSet.close();
        statement.close();

        disconnect();

        return listTodo;
    }

    public boolean deleteTodo(Todo todo) throws SQLException {
        String sql = "DELETE FROM todos where id = ?";

        connect();

        PreparedStatement statement = jdbcConnection.prepareStatement(sql);
        statement.setInt(1, todo.getId());

        boolean rowDeleted = statement.executeUpdate() > 0;
        statement.close();
        disconnect();
        return rowDeleted;
    }

    public boolean updateTodo(Todo todo) throws SQLException {
        String sql = "UPDATE todos SET title = ?, description = ?, is_completed = ?";
        sql += " WHERE id = ?";
        connect();

        PreparedStatement statement = jdbcConnection.prepareStatement(sql);
        statement.setString(1, todo.getTitle());
        statement.setString(2, todo.getDescription());
        statement.setBoolean(3, todo.isCompleted());
        statement.setInt(4, todo.getId());

        boolean rowUpdated = statement.executeUpdate() > 0;
        statement.close();
        disconnect();
        return rowUpdated;
    }

    public Todo getTodo(int id) throws SQLException {
        Todo todo = null;
        String sql = "SELECT * FROM todos WHERE id = ?";

        connect();

        PreparedStatement statement = jdbcConnection.prepareStatement(sql);
        statement.setInt(1, id);

        ResultSet resultSet = statement.executeQuery();

        if (resultSet.next()) {
            String title = resultSet.getString("title");
            String description = resultSet.getString("description");
            boolean isCompleted = resultSet.getBoolean("is_completed");

            todo = new Todo();
            todo.setId(id);
            todo.setTitle(title);
            todo.setDescription(description);
            todo.setCompleted(isCompleted);
        }

        resultSet.close();
        statement.close();

        return todo;
    }
}

Step 7: Create Servlet - TodoServlet.java

Create a TodoServlet class in the controller package to handle HTTP requests and responses, and redirect to the appropriate JSP pages.

package com.example.mvc.controller;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import com.example.mvc.dao.TodoDao;
import com.example.mvc.model.Todo;

@WebServlet("/todo")
public class TodoServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private TodoDao todoDao;

    public void init() {
        todoDao = new TodoDao();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        String action = request.getServletPath();

        try {
            switch (action) {
                case "/new":
                    showNewForm(request, response);
                    break;
                case "/insert":
                    insertTodo(request, response);
                    break;
                case "/delete":
                    deleteTodo(request, response);
                    break;
                case "/edit":
                    showEditForm(request, response);
                    break;
                case "/update":
                    updateTodo(request, response);
                    break;
                default:
                    listTodo(request, response);
                    break;
            }
        } catch (SQLException ex) {
            throw new ServletException(ex);
        }
    }

    private void listTodo(HttpServletRequest request, HttpServletResponse response)
    throws SQLException, IOException, ServletException {
        List<Todo> listTodo = todoDao.listAllTodos();
        request.setAttribute("listTodo", listTodo);
        RequestDispatcher dispatcher = request.getRequestDispatcher("todo-list.jsp");
        dispatcher.forward(request, response);
    }

    private void showNewForm(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        RequestDispatcher dispatcher = request.getRequestDispatcher("todo-form.jsp");
        dispatcher.forward(request, response);
    }

    private void showEditForm(HttpServletRequest request, HttpServletResponse response)
    throws SQLException, ServletException, IOException {
        int id = Integer.parseInt(request.getParameter("id"));
        Todo existingTodo = todoDao.getTodo(id);
        RequestDispatcher dispatcher = request.getRequestDispatcher("todo-form.jsp");
        request.setAttribute("todo", existingTodo);
        dispatcher.forward(request, response);
    }

    private void insertTodo(HttpServletRequest request, HttpServletResponse response)
    throws SQLException, IOException {
        String title = request.getParameter("title");
        String description = request.getParameter("description");
        boolean isCompleted = Boolean.parseBoolean(request.getParameter("isCompleted"));

        Todo newTodo = new Todo();
        newTodo.setTitle(title);
        newTodo.setDescription(description);
        newTodo.setCompleted(isCompleted);
        todoDao.insertTodo(newTodo);
        response.sendRedirect("list");
    }

    private void updateTodo(HttpServletRequest request, HttpServletResponse response)
    throws SQLException, IOException {
        int id = Integer.parseInt(request.getParameter("id"));
        String title = request.getParameter("title");
        String description = request.getParameter("description");
        boolean isCompleted = Boolean.parseBoolean(request.getParameter("isCompleted"));

        Todo todo = new Todo();
        todo.setId(id);
        todo.setTitle(title);
        todo.setDescription(description);
        todo.setCompleted(isCompleted);
        todoDao.updateTodo(todo);
        response.sendRedirect("list");
    }

    private void deleteTodo(HttpServletRequest request, HttpServletResponse response)
    throws SQLException, IOException {
        int id = Integer.parseInt(request.getParameter("id"));

        Todo todo = new Todo();
        todo.setId(id);
        todoDao.deleteTodo(todo);
        response.sendRedirect("list");
    }
}

Step 8: Create JSP Pages

index.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Todo Management Application</title>
</head>
<body>
 <div align="center">
  <h1>Todo Management Application</h1>
  <a href="new">Add New Todo</a>
  <br/>
  <a href="list">List All Todos</a>
 </div>
</body>
</html>

todo-form.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Todo Form</title>
</head>
<body>
 <div align="center">
  <h1>Todo Form</h1>
  <form action="${pageContext.request.contextPath}/todo" method="post">
   <table>
    <c:if test="${todo != null}">
     <tr>
      <td>ID</td>
      <td><input type="text" name="id" value="${todo.id}" readonly /></td>
     </tr>
    </c:if>
    <tr>
     <td>Title</td>
     <td><input type="text" name="title" value="${todo.title}" /></td>
    </tr>
    <tr>
     <td>Description</td>
     <td><input type="text" name="description" value="${todo.description}" /></td>
    </tr>
    <tr>
     <td>Completed</td>
     <td><input type="checkbox" name="isCompleted" ${todo.isCompleted ? 'checked' : ''} /></td>
    </tr>
    <tr>
     <td colspan="2">
      <input type="submit" value="Save" />
     </td>
    </tr>
   </table>
  </form>
 </div>
</body>
</html>

todo-list.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Todo List</title>
</head>
<body>
 <div align="center">
  <h1>Todo List</h1>
  <a href="new">Add New Todo</a>
  <br/>
  <table border="1">
   <tr>
    <th>ID</th>
    <th>Title</th>
    <th>Description</th>
    <th>Completed</th>
    <th>Actions</th>
   </tr>
   <c:forEach var="todo" items="${listTodo}">
    <tr>
     <td>${todo.id}</td>
     <td>${todo.title}</td>
     <td>${todo.description}</td>
     <td>${todo.isCompleted ? 'Yes' : 'No'}</td>
     <td>
      <a href="edit?id=${todo.id}">Edit</a>
      <a href="delete?id=${todo.id}">Delete</a>
     </td>
    </tr>
   </c:forEach>
  </table>
 </div>
</body>
</html>

Step 9: Demo

Once you deploy this application successfully, you can access it at http://localhost:8080/jsp-servlet-mvc-todo-example/index.jsp.

Conclusion

In this tutorial, we have demonstrated how to build a simple Todo management application using JSP, Servlet, JDBC, and MySQL database with the MVC design pattern. This example covers the basic CRUD operations and provides a solid foundation for building more complex web applications.

Related Servlet Posts

Comments