java servlet with tomcat

today we are going to discuss about Java servlet with Tomcat, the industry-standard web server. Learn how to create dynamic web applications, handle HTTP requests, and interact with databases using Java servlet technology. Dive into servlet lifecycle, request handling, session management, and more with practical examples and best practices.

what is servlet in java

A servlet in Java is a server-side program that handles client requests and generates dynamic responses, typically for web applications. Servlets run within a web server or application server and are part of the Java Servlet API, which is a standard for developing web-based applications in Java.

Common Issues and Fixes

  1. Database Connection: Ensure your database configuration is correct and the DataSource is properly set up in your application server (like Tomcat).
  2. Servlet Initialization: Ensure the servlet initializes correctly with a valid database connection.
  3. Form Actions: Ensure form actions in JSPs point to the correct servlet paths (insert, update, edit, delete).
  4. Check for Errors: Look at server logs for any exceptions or errors that might provide clues.

Controller Servlet

This servlet acts as the controller in the MVC (Model-View-Controller) architecture. It handles HTTP requests from clients, delegates business logic to the appropriate DAO methods, and forwards responses to JSP pages for rendering. It contains methods to handle various HTTP actions like doGet() and doPost(), and based on the request URL, it invokes corresponding methods to perform CRUD operations on books. It also initializes the BookDAO implementation during servlet initialization.

package com.book;


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

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.*;


public class ControllerServlet extends HttpServlet {
    private BookDAO bookDAO;

    @Override
    public void init() {
        bookDAO = new BookDAOImpl((Connection) getServletContext().getAttribute("conn"));
    }

    @Override
    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":
                    insertBook(request, response);
                    break;
                case "/delete":
                    deleteBook(request, response);
                    break;
                case "/edit":
                    showEditForm(request, response);
                    break;
                case "/update":
                    updateBook(request, response);
                    break;
                default:
                    listBook(request, response);
                    break;
            }
        } catch (SQLException ex) {
            throw new ServletException(ex);
        }
    }

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

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

        Book book = new Book();
        book.setId(id);
        book.setTitle(title);
        book.setAuthor(author);

        bookDAO.editBook(book);
        response.sendRedirect("list");
    }

    private void showEditForm(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        int id = Integer.parseInt(request.getParameter("id"));
        Book existingBook = bookDAO.getBook(id);
        RequestDispatcher dispatcher = request.getRequestDispatcher("BookForm.jsp");
        request.setAttribute("book", existingBook);
        dispatcher.forward(request, response);
    }

    private void insertBook(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, IOException {
        String title = request.getParameter("title");
        String author = request.getParameter("author");

        Book newBook = new Book();
        newBook.setTitle(title);
        newBook.setAuthor(author);
        bookDAO.addBook(newBook);
        response.sendRedirect("list");
    }

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

    private void deleteBook(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, IOException {
        int id = Integer.parseInt(request.getParameter("id"));
        bookDAO.deleteBook(id);
        response.sendRedirect("list");
    }


    private void listBook(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, IOException, ServletException {
        List<Book> listBook = bookDAO.listAllBooks();
        request.setAttribute("listBook", listBook);
        RequestDispatcher dispatcher = request.getRequestDispatcher("BookList.jsp");
        dispatcher.forward(request, response);
    }


}

Directory in java servlet with tomcat

The directory structure with all necessary files and configurations for your JSP and Servlet-based application.

java servlet with tomcat,
servlet in java

Configuring the Web Application

Make sure to include the necessary dependencies, such as the MySQL JDBC driver, and configure the web.xml file for servlet mapping.

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>CS</servlet-name>
    <servlet-class>com.book.ControllerServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>CS</servlet-name>
    <url-pattern>/cs</url-pattern>
  </servlet-mapping>
  <resource-ref>
    <description>MySQL Datasource</description>
    <res-ref-name>jdbc/MySQLDS</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
</web-app>

Key Functionalities:

  • Initialization: The init method initializes the BookDAO object using a database connection from the servlet context.
  • Routing: The doGet method uses a switch statement to handle different actions such as displaying forms for new or edited books, inserting new books, deleting existing books, and listing all books.

BookDAO and BookDAOImpl

The BookDAO interface defines the methods for interacting with the database, including listing all books, adding a new book, editing an existing book, and deleting a book by its ID.

package com.book;

import java.util.List;

public interface BookDAO {
    List<Book> listAllBooks();

    void addBook(Book book);
    void editBook(Book book);
    void deleteBook(int id);

    Book getBook(int id);
}

BookDAOImpl Implementation:

  • Database Initialization: The constructor initializes the DataSource using JNDI lookup and assigns the provided connection.
  • CRUD Operations: The implementation provides methods for executing SQL queries to perform the necessary CRUD operations. For instance, listAllBooks retrieves all records from the books table and populates a list of Book objects.
package com.book;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class BookDAOImpl implements BookDAO {
    private Connection conn;
    private DataSource dataSource;

    public BookDAOImpl(Connection conn) {
        try {
            InitialContext context = new InitialContext();
            dataSource = (DataSource) context.lookup("java:comp/env/jdbc/database");
            if (conn == null) {
                this.conn = dataSource.getConnection();
            } else {
                this.conn = conn;
            }
        } catch (NamingException | SQLException e) {
            throw new RuntimeException("Error initializing DataSource", e);
        }
    }

    public Book getBook(int id) {
        Book book = null;
        try {
            PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM books WHERE id = ?");
            pstmt.setInt(1, id);
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()) {
                book = new Book();
                book.setId(rs.getInt("id"));
                book.setTitle(rs.getString("title"));
                book.setAuthor(rs.getString("author"));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return book;
    }

    @Override
    public List<Book> listAllBooks() {
        List<Book> list = new ArrayList<>();
        try {
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT * FROM books");
            while (rs.next()) {
                Book book = new Book();
                book.setId(rs.getInt("id"));
                book.setTitle(rs.getString("title"));
                book.setAuthor(rs.getString("author"));
                list.add(book);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return list;
    }

    @Override
    public void addBook(Book book) {
        try {
            PreparedStatement pstmt = conn.prepareStatement("INSERT INTO books (title, author) VALUES (?,?)");
            pstmt.setString(1, book.getTitle());
            pstmt.setString(2, book.getAuthor());
            pstmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void editBook(Book book) {
        try {
            PreparedStatement pstmt = conn.prepareStatement("UPDATE books SET title =?, author =? WHERE id =?");
            pstmt.setString(1, book.getTitle());
            pstmt.setString(2, book.getAuthor());
            pstmt.setInt(3, book.getId());
            pstmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteBook(int id) {
        try {
            PreparedStatement pstmt = conn.prepareStatement("DELETE FROM books WHERE id =?");
            pstmt.setInt(1, id);
            pstmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

Book Entity

The Book class represents the book entity with attributes such as id, title, and author. It includes getter and setter methods for these attributes, enabling encapsulation and data manipulation.

package com.book;

public class Book {
    private int id;
    private String title;
    private String author;

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

    public int getId() {
        return  id;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getTitle() {
        return title;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getAuthor() {
        return author;
    }
}

Debugging Tips

  • Check Logs: Look at your application server logs (Tomcat logs) for any errors during startup or when performing actions.
  • Test Database Connection: Manually test the database connection to ensure the jdbc/database resource is correctly configured and accessible.
  • Step-by-Step Debugging: Add print statements or use a debugger to step through servlet methods to ensure the flow is as expected.

JSP Pages

The user interface for the book management system is created using JSP (JavaServer Pages). Below is a description of one of the JSP pages:

New Book Form:

The NewBook.jsp file provides a simple HTML form to input a new book’s title and author. When submitted, this form sends a POST request to the insert URL, which is handled by the ControllerServlet to add the new book to the database.

<!DOCTYPE html>
<html>
<head>
  <title>New Book</title>
</head>
<body>
<h1>New Book</h1>
<form action="insert" method="post">
  <label for="title">Title:</label>
  <input type="text" id="title" name="title" required><br>
  <label for="author">Author:</label>
  <input type="text" id="author" name="author" required><br>
  <input type="submit" value="Submit">
</form>
</body>
</html>

Conclusion

By following these steps, you can create a simple CRUD application with a clean separation of concerns using the DAO in java servlet. This structure makes your application more maintainable and scalable. Feel free to extend this basic setup with additional features like user authentication, input validation, and more sophisticated error handling.

Leave a comment