Kumar Goud
Kumar Goud
Description:
This experiment demonstrates how to implement a user authentication system for an online
bookstore using Java Servlets and JSP. The system starts by allowing users to log in through
a login.jsp page, where their credentials are captured and sent to the server. The LoginServlet
processes the credentials, checking the database (MySQL) for a matching username and
password using JDBC. If the login is successful, the system creates a session (HttpSession)
that stores the user's data (e.g., username), allowing access to restricted pages such as the
books.jsp page. If the login fails, the user is shown an error message, and they are prompted
to try again.
The system incorporates restricted access to certain pages using an authentication filter
(AuthFilter). This filter intercepts every request to check whether the user is authenticated by
examining their session. If the session contains valid user information, access is granted to
resources like the welcome page and the book catalog; otherwise, the user is redirected to the
login page. This ensures that users cannot access sensitive pages without being logged in. The
project follows the Model-View-Controller (MVC) design pattern, which separates the
application's business logic (handled by servlets) from the user interface (managed by JSPs),
ensuring maintainability and scalability.
85
Web Technologies Laboratory
86
Web Technologies Laboratory
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
}
87
Web Technologies Laboratory
chain.doFilter(request, response);
} else {
response.sendRedirect(loginURI);
}
}
public void destroy() {}
}
88
Web Technologies Laboratory
</form>
<% if (request.getAttribute("errorMessage") != null) { %>
<p class="error"><%= request.getAttribute("errorMessage") %></p>
<% } %>
</div>
</body>
</html>
89
Web Technologies Laboratory lll Year CSE C
<servlet-class>com.bookstore.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>BookServlet</servlet-name>
<servlet-class>com.bookstore.BookServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BookServlet</servlet-name>
<url-pattern>/BookServlet</url-pattern>
</servlet-mapping>
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>com.bookstore.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
1. Authentication Process:
- Users enter credentials on `login.jsp`
- `LoginServlet` validates credentials against the database
- Successful login creates a session with username attribute
- Failed login displays error message
2. Access Control:
- `AuthFilter` intercepts all requests
- Only authenticated users can access protected pages (`welcome.jsp`, `books.jsp`)
- Unauthenticated users are redirected to login page
90
Web Technologies Laboratory lll Year CSE C
3. Session Management:
- User session is maintained using HttpSession
- Username is stored in session after successful login
- Session validation occurs for protected resources
4. Protected Resources:
- Welcome page displays user-specific greeting
- Books page shows available books (protected by filter)
- Logout functionality invalidates session
Output:
91
Web Technologies Laboratory lll Year CSE C
92
Web Technologies Laboratory lll Year CSE C
Aim: To work with the provided Servlet/JSP and Hibernate-based online bookstore
application in Eclipse and ensure correct output, please follow these steps for project setup,
file organization within appropriate directories, environment configuration, and application
deployment on a server (e.g., Apache Tomcat). The step-by-step guide below will assist you
in Eclipse IDE.
Description:
In this experiment, students will learn how to set up and deploy a full-fledged online bookstore
web application using Servlets, JSP, and Hibernate technologies within the Eclipse IDE.
The application includes user authentication, session management, database operations, and
dynamic web content generation. Students begin by creating a Dynamic Web Project in Eclipse,
configuring Apache Tomcat as the servlet container, and setting up the project structure
according to Java EE standards. They will also integrate Hibernate ORM for managing
database transactions with MySQL, enabling seamless interaction between Java objects and
relational database tables.
The setup process involves properly organizing source files, JSP pages, servlet classes, and
configuration files (like web.xml and hibernate.cfg.xml) into correct directories such as
src/main/java, src/main/resources, and src/main/webapp. Dependencies like MySQL
Connector, Hibernate Core, and JSTL libraries are managed through Maven, ensuring
efficient project build and management. Special attention is given to configuring Hibernate
mappings for the User and Book entities, setting up a MySQL database schema, and validating
connections to ensure correct application behavior.
Additionally, the deployment process includes server configuration, running the project on
Tomcat Server from within Eclipse, and troubleshooting common errors like servlet mapping
issues, missing libraries, or database connectivity problems. Students will verify the correct
functioning of user login, book listing, session handling, and access restrictions using filters.
Through this hands-on exercise, learners gain practical experience in building enterprise-grade
Java web applications and understand the critical role of environment setup, project
organization, and full-stack development in professional software engineering.
93
Web Technologies Laboratory lll Year CSE C
Prerequisites
Eclipse IDE: Use Eclipse IDE for Java EE Developers (version 2023-09 or later recommended).
Java: JDK 17 or later installed and configured.
Tomcat: Apache Tomcat 10.x installed and integrated with Eclipse.
MySQL: MySQL server installed with the bookstore database created (use the SQL provided
earlier).
Dependencies: Hibernate, MySQL Connector, and JSTL libraries (can be managed via Maven).
Maven: Optional but recommended for dependency management.
94
Web Technologies Laboratory lll Year CSE C
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
<!-- JSTL -->
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>2.0.0</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.4.0.Final</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- C3P0 for Hibernate connection pooling -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugins>
</build>
95
Web Technologies Laboratory lll Year CSE C
</project>
<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 http://maven.apache.org/xsd/maven-
4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bookstore</groupId>
<artifactId>BookStore</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- Jakarta Servlet API -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
<!-- Jakarta JSP API -->
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
<!-- JSTL -->
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>2.0.0</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.4.0.Final</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- C3P0 for Hibernate connection pooling -->
<dependency>
<groupId>com.mchange</groupId>
96
Web Technologies Laboratory lll Year CSE C
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugins>
</build>
</project>
Save pom.xml and run Maven > Update Project (right-click project > Maven > Update
Project).
97
Web Technologies Laboratory lll Year CSE C
│ │ ├── books.jsp
│ │ └── error.jsp
│ └── index.jsp (optional redirect to login.jsp)
98
Web Technologies Laboratory lll Year CSE C
INSERT INTO books (title, author, price, isbn) VALUES ('Java Programming', 'John Smith', 29.99,
'1234567890123');
Verify Connection:
o Ensure MySQL is running.
o Update hibernate.cfg.xml and DatabaseConnection.java (if using JDBC fallback) with
the correct your_password.
If using Maven, Eclipse automatically manages dependencies after updating the project.
99
Web Technologies Laboratory lll Year CSE C
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.4.0.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
Entity Classs
1. User Entity (User.java)
The User entity represents a user in the bookstore system, with fields like username, password, and a
list of associated books.
package com.bookstore.entity;
import jakarta.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "users")
public class User {
@Id
100
Web Technologies Laboratory lll Year CSE C
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "username", unique = true, nullable = false, length = 50)
private String username;
@Column(name = "password", nullable = false, length = 255)
private String password;
@Column(name = "email", unique = true, nullable = false, length = 100)
private String email;
// One user can have many books (e.g., wishlist or purchased books)
@ManyToMany
@JoinTable(
name = "user_books",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "book_id")
)
private List<Book> books = new ArrayList<>();
// Constructors
public User() {}
public User(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
// Getters and Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public List<Book> getBooks() { return books; }
public void setBooks(List<Book> books) { this.books = books; }
// Helper methods for managing books
public void addBook(Book book) {
books.add(book);
book.getUsers().add(this);
}
public void removeBook(Book book) {
books.remove(book);
book.getUsers().remove(this);
}
@Override
public String toString() {
return "User{id=" + id + ", username='" + username + "', email='" + email + "'}";
}
}
101
Web Technologies Laboratory lll Year CSE C
102
Web Technologies Laboratory lll Year CSE C
}
}
Database Schema
The corresponding SQL to create the tables:
CREATE DATABASE bookstore;
USE bookstore;
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL
);
CREATE TABLE books (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(100) NOT NULL,
author VARCHAR(100) NOT NULL,
price DECIMAL(10, 2) NOT NULL,
isbn VARCHAR(13) UNIQUE NOT NULL
);
CREATE TABLE user_books (
user_id BIGINT NOT NULL,
book_id BIGINT NOT NULL,
PRIMARY KEY (user_id, book_id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (book_id) REFERENCES books(id)
);
103
Web Technologies Laboratory lll Year CSE C
Output:
104
Web Technologies Laboratory lll Year CSE C
Aim: Implement CRUD (Create, Read, Update, Delete) operations using Hibernate for
managing book information in the online bookstore database, integrating with the existing
Servlet/JSP application. Extend the previous setup to include a complete solution for handling
books, assuming the Book and User entities are already defined as provided. The
implementation will include a DAO (Data Access Object) layer, updated servlets, and JSP
pages for user interaction.
Description:
In this experiment, students will extend the existing online bookstore application by
implementing complete CRUD (Create, Read, Update, Delete) operations for managing book
information in the database. Using Hibernate ORM, they will interact with the books table,
allowing users to add new books, view all available books, edit existing book details, and delete
books when necessary. The system integrates seamlessly with the current Servlet/JSP
architecture, and ensures that only authenticated users can perform these operations.
A structured DAO (Data Access Object) layer is introduced to abstract and encapsulate all
database interactions related to the Book entity, promoting better code reusability and
maintainability. The experiment also involves updating servlets to handle new requests for
book creation, editing, deletion, and listing, while JSP pages are modified to provide intuitive
interfaces for these operations. Hibernate mappings are leveraged to ensure efficient and error-
free persistence of data between Java objects and the MySQL database.
Through this exercise, students will understand how to apply Hibernate in a real-world web
application, organize application layers effectively (presentation, service, and persistence
layers), and manage database operations in an enterprise-standard manner. By the end, learners
will have developed a fully functional book management module integrated into the existing
bookstore system, further strengthening their skills in full-stack Java web development.
105
Web Technologies Laboratory lll Year CSE C
Project Context
Entities: Using the Book entity from the previous response (com.bookstore.entity.Book).
Database: MySQL with the bookstore database and books table.
Existing Setup: Servlet-based authentication with LoginServlet, BookServlet, AuthFilter, and
JSPs (login.jsp, welcome.jsp, books.jsp).
Goal: Add CRUD operations for books, accessible to authenticated users (e.g., an admin role
could be added later).
BookDAO.java:
package com.bookstore.dao;
import com.bookstore.entity.Book;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import java.util.List;
public class BookDAO {
private final SessionFactory sessionFactory;
public BookDAO(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
// Create
public void createBook(Book book) {
try (Session session = sessionFactory.openSession()) {
session.beginTransaction();
session.persist(book);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to create book", e);
}
}
// Read (single book by ID)
public Book getBook(Long id) {
try (Session session = sessionFactory.openSession()) {
return session.find(Book.class, id);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to retrieve book with id: " + id, e);
}
}
// Read (all books)
public List<Book> getAllBooks() {
try (Session session = sessionFactory.openSession()) {
Query<Book> query = session.createQuery("FROM Book", Book.class);
return query.getResultList();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to retrieve books", e);
106
Web Technologies Laboratory lll Year CSE C
}
}
// Update
public void updateBook(Book book) {
try (Session session = sessionFactory.openSession()) {
session.beginTransaction();
session.merge(book);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to update book", e);
}
}
// Delete
public void deleteBook(Long id) {
try (Session session = sessionFactory.openSession()) {
session.beginTransaction();
Book book = session.find(Book.class, id);
if (book != null) {
session.remove(book);
}
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to delete book with id: " + id, e);
}
}
}
HibernateUtil.java:
package com.bookstore.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration()
.configure("hibernate.cfg.xml")
.buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
107
Web Technologies Laboratory lll Year CSE C
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
getSessionFactory().close();
}
}
DatabaseConnection.java:
package com.bookstore;
import com.bookstore.entity.User;
import com.bookstore.util.HibernateUtil;
import org.hibernate.Session;
public class DatabaseConnection {
public static boolean validateUser(String username, String password) {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
User user = session.createQuery("FROM User WHERE username = :username AND
password = :password", User.class)
.setParameter("username", username)
.setParameter("password", password)
.uniqueResult();
return user != null;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
BookManagementServlet.java:
package com.bookstore;
import com.bookstore.dao.BookDAO;
import com.bookstore.entity.Book;
import com.bookstore.util.HibernateUtil;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
108
Web Technologies Laboratory lll Year CSE C
109
Web Technologies Laboratory lll Year CSE C
books.jsp (Updated):
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>Book Catalog</title>
110
Web Technologies Laboratory lll Year CSE C
<style>
table { border-collapse: collapse; width: 80%; margin: 20px auto; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.actions a { margin-right: 10px; }
.add-button { display: block; width: 100px; margin: 20px auto; text-align: center; }
</style>
</head>
<body>
<h2>Book Catalog</h2>
<a href="BookManagementServlet?action=create" class="add-button">Add New Book</a>
<table>
<tr>
<th>Title</th>
<th>Author</th>
<th>Price</th>
<th>ISBN</th>
<th>Actions</th>
</tr>
<c:forEach items="${books}" var="book">
<tr>
<td>${book.title}</td>
<td>${book.author}</td>
<td>${book.price}</td>
<td>${book.isbn}</td>
<td class="actions">
<a href="BookManagementServlet?action=edit&id=${book.id}">Edit</a>
<a href="BookManagementServlet?action=delete&id=${book.id}"
onclick="return confirm('Are you sure you want to delete this book?')">Delete</a>
</td>
</tr>
</c:forEach>
</table>
<a href="welcome.jsp">Back to Home</a>
</body>
</html>
book-form.jsp (New):
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>${book == null ? 'Add New Book' : 'Edit Book'}</title>
<style>
.form-container { width: 300px; margin: 50px auto; }
label { display: block; margin: 10px 0 5px; }
input { width: 100%; padding: 5px; }
button { margin-top: 10px; padding: 5px 10px; }
</style>
</head>
111
Web Technologies Laboratory lll Year CSE C
<body>
<div class="form-container">
<h2>${book == null ? 'Add New Book' : 'Edit Book'}</h2>
<form action="BookManagementServlet" method="post">
<input type="hidden" name="action" value="${book == null ? 'create' : 'update'}">
<c:if test="${book != null}">
<input type="hidden" name="id" value="${book.id}">
</c:if>
<label>Title:</label>
<input type="text" name="title" value="${book.title}" required>
<label>Author:</label>
<input type="text" name="author" value="${book.author}" required>
<label>Price:</label>
<input type="number" step="0.01" name="price" value="${book.price}" required>
<label>ISBN:</label>
<input type="text" name="isbn" value="${book.isbn}" required>
<button type="submit">Save</button>
</form>
<a href="BookManagementServlet">Cancel</a>
</div>
</body>
</html>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.bookstore.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>BookManagementServlet</servlet-name>
<servlet-class>com.bookstore.BookManagementServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BookManagementServlet</servlet-name>
<url-pattern>/BookManagementServlet</url-pattern>
</servlet-mapping>
<filter>
<filter-name>AuthFilter</filter-name>
112
Web Technologies Laboratory lll Year CSE C
<filter-class>com.bookstore.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
welcome.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Welcome to BookStore</title>
</head>
<body>
<h2>Welcome, <%= session.getAttribute("username") %>!</h2>
<a href="BookManagementServlet">Manage Books</a><br>
<a href="logout">Logout</a>
</body>
</html>
113
Web Technologies Laboratory lll Year CSE C
│ │ ├── web.xml
│ │ └── views
│ │ ├── login.jsp
│ │ ├── welcome.jsp
│ │ ├── books.jsp
│ │ ├── book-form.jsp
│ │ └── error.jsp
114
Web Technologies Laboratory lll Year CSE C
115
Web Technologies Laboratory lll Year CSE C
116
Web Technologies Laboratory lll Year CSE C
Aim: Enhance the shopping cart functionality in the online bookstore application by integrating
JavaScript with Servlets. Implement an AJAX-based solution that allows users to add, update,
and remove books from their cart without refreshing the page. This will build on the existing
Servlet/JSP and Hibernate setup, using JavaScript (with Fetch API) to communicate
asynchronously with servlets. The cart will be stored in the user's session, and the UI will
update dynamically.
Description:
In this experiment, students will enhance the user experience of the online bookstore
application by integrating AJAX functionality into the shopping cart system. Using
JavaScript (specifically the Fetch API), the application allows users to add, update, and
remove books from their shopping cart without requiring a page reload. The shopping cart
data is stored securely in the user's HTTP session, and any cart operations trigger asynchronous
communication with server-side servlets to dynamically update the UI.
The experiment builds upon the existing Servlet/JSP and Hibernate infrastructure. A new
CartServlet is introduced to handle AJAX requests, and JSP pages are modified to include
interactive elements such as quantity selectors, "Add to Cart" buttons, and live cart updates.
JSON is used as the data exchange format between the client and server, ensuring smooth and
lightweight communication. The project emphasizes modern web development practices by
decoupling front-end user actions from server responses, improving application responsiveness
and overall usability.
Through this exercise, students gain hands-on experience in integrating front-end technologies
with traditional Java EE back-end systems. They also learn how to implement session-based
cart management, asynchronous data handling, and real-time UI updates, thus equipping them
with skills essential for developing dynamic, user-friendly, full-stack web applications.
117
Web Technologies Laboratory lll Year CSE C
Project Context
Existing Setup: Servlet-based authentication (LoginServlet, AuthFilter), Hibernate for book
management (BookDAO, BookManagementServlet), and JSPs (login.jsp, welcome.jsp,
books.jsp, book-form.jsp).
Entities: User and Book (from previous responses).
Database: MySQL bookstore with users, books, and user_books tables.
Goal: Add a shopping cart where authenticated users can:
o Add books to the cart.
o Update quantities.
o Remove books.
o View the cart, all without page refresh.
Update User.java (optional): For now, we'll store the cart in the session as a List<CartItem> rather
than modifying User. If you want persistent carts, we can add a List<CartItem> to User and a new
table later.
CartServlet.java:
package com.bookstore;
import com.bookstore.dao.BookDAO;
import com.bookstore.entity.Book;
import com.bookstore.entity.CartItem;
import com.bookstore.util.HibernateUtil;
118
Web Technologies Laboratory lll Year CSE C
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
public class CartServlet extends HttpServlet {
private BookDAO bookDAO;
@Override
public void init() throws ServletException {
bookDAO = new BookDAO(HibernateUtil.getSessionFactory());
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
if ("view".equals(action)) {
viewCart(request, response);
} else {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid action");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
response.setContentType("application/json");
PrintWriter out = response.getWriter();
switch (action) {
case "add":
addToCart(request, response, out);
break;
case "update":
updateCart(request, response, out);
break;
case "remove":
removeFromCart(request, response, out);
break;
default:
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid action");
}
}
private void addToCart(HttpServletRequest request, HttpServletResponse response, PrintWriter
out)
throws IOException {
Long bookId = Long.parseLong(request.getParameter("bookId"));
119
Web Technologies Laboratory lll Year CSE C
120
Web Technologies Laboratory lll Year CSE C
}
private void viewCart(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
List<CartItem> cart = getCart(session);
request.setAttribute("cart", cart);
request.getRequestDispatcher("WEB-INF/views/cart.jsp").forward(request, response);
}
private List<CartItem> getCart(HttpSession session) {
List<CartItem> cart = (List<CartItem>) session.getAttribute("cart");
if (cart == null) {
cart = new ArrayList<>();
session.setAttribute("cart", cart);
}
return cart;
}
private void sendCartResponse(PrintWriter out, List<CartItem> cart) {
JSONObject responseJson = new JSONObject();
JSONArray cartItems = new JSONArray();
BigDecimal total = BigDecimal.ZERO;
for (CartItem item : cart) {
JSONObject itemJson = new JSONObject();
itemJson.put("bookId", item.getBook().getId());
itemJson.put("title", item.getBook().getTitle());
itemJson.put("author", item.getBook().getAuthor());
itemJson.put("price", item.getBook().getPrice());
itemJson.put("quantity", item.getQuantity());
itemJson.put("subtotal", item.getSubtotal());
cartItems.put(itemJson);
total = total.add(item.getSubtotal());
}
responseJson.put("cart", cartItems);
responseJson.put("total", total);
out.print(responseJson.toString());
out.flush();
}
private void sendErrorResponse(PrintWriter out, String message) {
JSONObject responseJson = new JSONObject();
responseJson.put("error", message);
out.print(responseJson.toString());
out.flush();
}
}
121
Web Technologies Laboratory lll Year CSE C
books.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>Book Catalog</title>
<style>
table { border-collapse: collapse; width: 80%; margin: 20px auto; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.actions a { margin-right: 10px; }
.add-button { display: block; width: 100px; margin: 20px auto; text-align: center; }
.cart-button { padding: 5px; cursor: pointer; }
.quantity-input { width: 50px; }
#cart-notification { position: fixed; top: 10px; right: 10px; background: #4CAF50; color: white;
padding: 10px; display: none; }
</style>
</head>
<body>
<h2>Book Catalog</h2>
<div id="cart-notification"></div>
<a href="BookManagementServlet?action=create" class="add-button">Add New Book</a>
<a href="CartServlet?action=view" class="add-button">View Cart</a>
<table>
<tr>
<th>Title</th>
<th>Author</th>
<th>Price</th>
<th>ISBN</th>
<th>Actions</th>
<th>Cart</th>
</tr>
<c:forEach items="${books}" var="book">
<tr>
<td>${book.title}</td>
<td>${book.author}</td>
<td>${book.price}</td>
<td>${book.isbn}</td>
<td class="actions">
<a href="BookManagementServlet?action=edit&id=${book.id}">Edit</a>
<a href="BookManagementServlet?action=delete&id=${book.id}"
onclick="return confirm('Are you sure you want to delete this book?')">Delete</a>
</td>
<td>
<input type="number" class="quantity-input" id="quantity-${book.id}" value="1"
min="1">
<button class="cart-button" onclick="addToCart(${book.id})">Add to Cart</button>
122
Web Technologies Laboratory lll Year CSE C
</td>
</tr>
</c:forEach>
</table>
<a href="welcome.jsp">Back to Home</a>
<script>
function addToCart(bookId) {
const quantity = document.getElementById(`quantity-${bookId}`).value;
fetch('CartServlet', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `action=add&bookId=${bookId}&quantity=${quantity}`
})
.then(response => response.json())
.then(data => {
if (data.error) {
showNotification('Error: ' + data.error, 'red');
} else {
showNotification('Book added to cart!', 'green');
}
})
.catch(error => showNotification('Error adding to cart', 'red'));
}
function showNotification(message, color) {
const notification = document.getElementById('cart-notification');
notification.textContent = message;
notification.style.backgroundColor = color === 'green' ? '#4CAF50' : '#f44336';
notification.style.display = 'block';
setTimeout(() => notification.style.display = 'none', 3000);
}
</script>
</body>
</html>
cart.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>Shopping Cart</title>
<style>
table { border-collapse: collapse; width: 80%; margin: 20px auto; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.quantity-input { width: 50px; }
.update-button, .remove-button { padding: 5px; cursor: pointer; }
123
Web Technologies Laboratory lll Year CSE C
#cart-notification { position: fixed; top: 10px; right: 10px; background: #4CAF50; color: white;
padding: 10px; display: none; }
.total { font-weight: bold; margin: 20px; }
</style>
</head>
<body>
<h2>Shopping Cart</h2>
<div id="cart-notification"></div>
<table id="cart-table">
<tr>
<th>Title</th>
<th>Author</th>
<th>Price</th>
<th>Quantity</th>
<th>Subtotal</th>
<th>Actions</th>
</tr>
<c:forEach items="${cart}" var="item">
<tr data-book-id="${item.book.id}">
<td>${item.book.title}</td>
<td>${item.book.author}</td>
<td>${item.book.price}</td>
<td>
<input type="number" class="quantity-input" value="${item.quantity}" min="1"
onchange="updateCart(${item.book.id}, this.value)">
</td>
<td class="subtotal">${item.subtotal}</td>
<td>
<button class="remove-button"
onclick="removeFromCart(${item.book.id})">Remove</button>
</td>
</tr>
</c:forEach>
</table>
<div class="total" id="cart-total">
Total: $<span id="total-amount"><c:out value="${cart.stream().map(item ->
item.subtotal).reduce(BigDecimal.ZERO, BigDecimal::add)}"/></span>
</div>
<a href="BookManagementServlet">Continue Shopping</a>
<script>
function updateCart(bookId, quantity) {
fetch('CartServlet', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `action=update&bookId=${bookId}&quantity=${quantity}`
})
.then(response => response.json())
.then(data => {
if (data.error) {
showNotification('Error: ' + data.error, 'red');
124
Web Technologies Laboratory lll Year CSE C
} else {
updateCartUI(data);
showNotification('Cart updated!', 'green');
}
})
.catch(error => showNotification('Error updating cart', 'red'));
}
function removeFromCart(bookId) {
fetch('CartServlet', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `action=remove&bookId=${bookId}`
})
.then(response => response.json())
.then(data => {
if (data.error) {
showNotification('Error: ' + data.error, 'red');
} else {
updateCartUI(data);
showNotification('Book removed from cart!', 'green');
}
})
.catch(error => showNotification('Error removing from cart', 'red'));
}
function updateCartUI(data) {
const table = document.getElementById('cart-table');
// Clear existing rows except header
while (table.rows.length > 1) {
table.deleteRow(1);
}
// Add new rows
data.cart.forEach(item => {
const row = table.insertRow();
row.setAttribute('data-book-id', item.bookId);
row.insertCell(0).textContent = item.title;
row.insertCell(1).textContent = item.author;
row.insertCell(2).textContent = item.price;
const quantityCell = row.insertCell(3);
quantityCell.innerHTML = `<input type="number" class="quantity-input"
value="${item.quantity}" min="1"
onchange="updateCart(${item.bookId}, this.value)">`;
row.insertCell(4).textContent = item.subtotal;
const actionCell = row.insertCell(5);
actionCell.innerHTML = `<button class="remove-button"
onclick="removeFromCart(${item.bookId})">Remove</button>`;
});
// Update total
document.getElementById('total-amount').textContent = data.total;
}
function showNotification(message, color) {
const notification = document.getElementById('cart-notification');
125
Web Technologies Laboratory lll Year CSE C
notification.textContent = message;
notification.style.backgroundColor = color === 'green' ? '#4CAF50' : '#f44336';
notification.style.display = 'block';
setTimeout(() => notification.style.display = 'none', 3000);
}
</script>
</body>
</html>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.bookstore.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>BookManagementServlet</servlet-name>
<servlet-class>com.bookstore.BookManagementServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BookManagementServlet</servlet-name>
<url-pattern>/BookManagementServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CartServlet</servlet-name>
<servlet-class>com.bookstore.CartServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CartServlet</servlet-name>
<url-pattern>/CartServlet</url-pattern>
</servlet-mapping>
<filter>
<filter-name>AuthFilter</filter-name>
<servlet-class>com.bookstore.AuthFilter</servlet-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
126
Web Technologies Laboratory lll Year CSE C
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
New Files:
o CartItem.java in com.bookstore.entity.
o CartServlet.java in com.bookstore.
o cart.jsp in WEB-INF/views.
127
Web Technologies Laboratory lll Year CSE C
128
Web Technologies Laboratory lll Year CSE C
Aim: Implement a checkout process for the online bookstore application, building on the
existing Servlet/JSP and Hibernate setup with the shopping cart functionality. The checkout
process will allow authenticated users to review their cart, enter shipping information, and
complete the purchase. The solution will use servlets to handle backend logic, JSPs for the
frontend, and Hibernate to persist order data in the database. The cart will be cleared upon
successful checkout, and an order confirmation will be displayed.
Description:
In this experiment, students will develop a complete checkout process for the online bookstore
web application. Building on the previously implemented shopping cart functionality, the
checkout flow will enable authenticated users to review the items in their cart, provide
shipping information, and finalize their purchases. The solution uses Servlets for handling
backend logic, JSP pages for user interaction, and Hibernate ORM to persist the order and
shipping details into a MySQL database.
During the checkout, users will be presented with a summary of their cart contents along with
a form to enter essential shipping details like address, contact number, and payment
information (optional for this basic setup). Upon submitting the form, the system will create a
new order record in the database, associating it with the user and storing the purchased books.
After a successful checkout, the user's cart will be cleared from the session, and an order
confirmation page will be displayed to acknowledge the completed transaction.
Through this experiment, students will learn how to manage transaction flow in a real-world
web application, handle form data securely, maintain proper session management, and persist
relational data using Hibernate. It also emphasizes integrating multiple technologies cohesively
to build a seamless and user-friendly e-commerce experience.
129
Web Technologies Laboratory lll Year CSE C
Project Context
Existing Setup:
o Servlets: LoginServlet, BookManagementServlet, CartServlet, AuthFilter.
o JSPs: login.jsp, welcome.jsp, books.jsp, book-form.jsp, cart.jsp.
o Entities: User, Book, CartItem.
o Hibernate: Manages users, books, user_books tables, with BookDAO and
HibernateUtil.
o Cart: Stored in session as List<CartItem>, managed via AJAX in CartServlet.
Database: MySQL bookstore database.
Goal: Implement a checkout process where users:
o Review cart contents.
o Enter shipping details (name, address, etc.).
o Submit the order, which saves to the database and clears the cart.
o View an order confirmation.
SQL:
USE bookstore;
CREATE TABLE orders (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
order_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
shipping_name VARCHAR(100) NOT NULL,
shipping_address VARCHAR(255) NOT NULL,
shipping_city VARCHAR(50) NOT NULL,
shipping_state VARCHAR(50) NOT NULL,
shipping_zip VARCHAR(10) NOT NULL,
total_amount DECIMAL(10, 2) NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE TABLE order_items (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
order_id BIGINT NOT NULL,
book_id BIGINT NOT NULL,
quantity INT NOT NULL,
price DECIMAL(10, 2) NOT NULL,
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (book_id) REFERENCES books(id)
);
Order.java:
package com.bookstore.entity;
import jakarta.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
130
Web Technologies Laboratory lll Year CSE C
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@Column(name = "order_date", nullable = false)
private LocalDateTime orderDate;
@Column(name = "shipping_name", nullable = false)
private String shippingName;
@Column(name = "shipping_address", nullable = false)
private String shippingAddress;
@Column(name = "shipping_city", nullable = false)
private String shippingCity;
@Column(name = "shipping_state", nullable = false)
private String shippingState;
@Column(name = "shipping_zip", nullable = false)
private String shippingZip;
@Column(name = "total_amount", nullable = false)
private BigDecimal totalAmount;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderItem> orderItems = new ArrayList<>();
// Constructors
public Order() {
this.orderDate = LocalDateTime.now();
}
// Getters and Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public User getUser() { return user; }
public void setUser(User user) { this.user = user; }
public LocalDateTime getOrderDate() { return orderDate; }
public void setOrderDate(LocalDateTime orderDate) { this.orderDate = orderDate; }
public String getShippingName() { return shippingName; }
public void setShippingName(String shippingName) { this.shippingName = shippingName; }
public String getShippingAddress() { return shippingAddress; }
public void setShippingAddress(String shippingAddress) { this.shippingAddress =
shippingAddress; }
public String getShippingCity() { return shippingCity; }
public void setShippingCity(String shippingCity) { this.shippingCity = shippingCity; }
public String getShippingState() { return shippingState; }
public void setShippingState(String shippingState) { this.shippingState = shippingState; }
public String getShippingZip() { return shippingZip; }
public void setShippingZip(String shippingZip) { this.shippingZip = shippingZip; }
131
Web Technologies Laboratory lll Year CSE C
OrderItem.java:
package com.bookstore.entity;
import jakarta.persistence.*;
import java.math.BigDecimal;
@Entity
@Table(name = "order_items")
public class OrderItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id", nullable = false)
private Order order;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "book_id", nullable = false)
private Book book;
@Column(name = "quantity", nullable = false)
private int quantity;
@Column(name = "price", nullable = false)
private BigDecimal price;
// Constructors
public OrderItem() {}
public OrderItem(Book book, int quantity, BigDecimal price) {
this.book = book;
this.quantity = quantity;
this.price = price;
}
// Getters and Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public Order getOrder() { return order; }
public void setOrder(Order order) { this.order = order; }
public Book getBook() { return book; }
public void setBook(Book book) { this.book = book; }
public int getQuantity() { return quantity; }
public void setQuantity(int quantity) { this.quantity = quantity; }
public BigDecimal getPrice() { return price; }
public void setPrice(BigDecimal price) { this.price = price; }
}
132
Web Technologies Laboratory lll Year CSE C
133
Web Technologies Laboratory lll Year CSE C
}
public void removeBook(Book book) {
books.remove(book);
book.getUsers().remove(this);
}
public void addOrder(Order order) {
orders.add(order);
order.setUser(this);
}
}
OrderDAO.java:
package com.bookstore.dao;
import com.bookstore.entity.Order;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
134
Web Technologies Laboratory lll Year CSE C
CheckoutServlet.java:
package com.bookstore;
import com.bookstore.dao.OrderDAO;
import com.bookstore.entity.*;
import com.bookstore.util.HibernateUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
public class CheckoutServlet extends HttpServlet {
private OrderDAO orderDAO;
@Override
public void init() throws ServletException {
orderDAO = new OrderDAO(HibernateUtil.getSessionFactory());
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
135
Web Technologies Laboratory lll Year CSE C
136
Web Technologies Laboratory lll Year CSE C
// Create order
Order order = new Order();
order.setShippingName(shippingName);
order.setShippingAddress(shippingAddress);
order.setShippingCity(shippingCity);
order.setShippingState(shippingState);
order.setShippingZip(shippingZip);
order.setOrderDate(LocalDateTime.now());
// Get user from session
try (var sessionFactory = HibernateUtil.getSessionFactory();
var hibernateSession = sessionFactory.openSession()) {
User user = hibernateSession.createQuery("FROM User WHERE username = :username",
User.class)
.setParameter("username", session.getAttribute("username"))
.uniqueResult();
order.setUser(user);
}
// Calculate total and add order items
BigDecimal total = BigDecimal.ZERO;
for (CartItem cartItem : cart) {
OrderItem orderItem = new OrderItem(cartItem.getBook(), cartItem.getQuantity(),
cartItem.getBook().getPrice());
order.addOrderItem(orderItem);
total = total.add(cartItem.getSubtotal());
}
order.setTotalAmount(total);
// Save order
orderDAO.createOrder(order);
// Clear cart
session.removeAttribute("cart");
// Store order for confirmation
session.setAttribute("order", order);
// Redirect to confirmation
response.sendRedirect("CheckoutServlet?action=confirm");
}
private void showConfirmation(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
Order order = (Order) session.getAttribute("order");
if (order == null) {
response.sendRedirect("CartServlet?action=view");
return;
}
request.setAttribute("order", order);
session.removeAttribute("order"); // Clean up
request.getRequestDispatcher("WEB-INF/views/order-confirmation.jsp").forward(request,
response);
}
}
137
Web Technologies Laboratory lll Year CSE C
checkout.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>Checkout</title>
<style>
.container { width: 80%; margin: 20px auto; }
table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; }
input, select { width: 100%; padding: 8px; }
.error { color: red; }
.total { font-weight: bold; }
button { padding: 10px 20px; cursor: pointer; }
</style>
</head>
<body>
<div class="container">
<h2>Checkout</h2>
<h3>Review Your Cart</h3>
<table>
<tr>
<th>Title</th>
<th>Author</th>
<th>Price</th>
<th>Quantity</th>
<th>Subtotal</th>
</tr>
<c:forEach items="${cart}" var="item">
<tr>
<td>${item.book.title}</td>
<td>${item.book.author}</td>
<td>${item.book.price}</td>
<td>${item.quantity}</td>
<td>${item.subtotal}</td>
</tr>
</c:forEach>
</table>
<div class="total">
Total: $<c:out value="${cart.stream().map(item -> item.subtotal).reduce(BigDecimal.ZERO,
BigDecimal::add)}"/>
</div>
<h3>Shipping Information</h3>
<c:if test="${not empty errorMessage}">
138
Web Technologies Laboratory lll Year CSE C
<p class="error">${errorMessage}</p>
</c:if>
<form action="CheckoutServlet" method="post">
<input type="hidden" name="action" value="submit">
<div class="form-group">
<label for="shippingName">Full Name:</label>
<input type="text" id="shippingName" name="shippingName" required>
</div>
<div class="form-group">
<label for="shippingAddress">Address:</label>
<input type="text" id="shippingAddress" name="shippingAddress" required>
</div>
<div class="form-group">
<label for="shippingCity">City:</label>
<input type="text" id="shippingCity" name="shippingCity" required>
</div>
<div class="form-group">
<label for="shippingState">State:</label>
<input type="text" id="shippingState" name="shippingState" required>
</div>
<div class="form-group">
<label for="shippingZip">ZIP Code:</label>
<input type="text" id="shippingZip" name="shippingZip" required>
</div>
<button type="submit">Place Order</button>
</form>
<a href="CartServlet?action=view">Back to Cart</a>
</div>
</body>
</html>
order-confirmation.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>Order Confirmation</title>
<style>
.container { width: 80%; margin: 20px auto; }
table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.total { font-weight: bold; }
.shipping-info { margin-bottom: 20px; }
</style>
</head>
<body>
139
Web Technologies Laboratory lll Year CSE C
<div class="container">
<h2>Order Confirmation</h2>
<p>Thank you for your purchase!</p>
<h3>Order Details</h3>
<p>Order ID: ${order.id}</p>
<p>Order Date: ${order.orderDate}</p>
<div class="shipping-info">
<h4>Shipping Information</h4>
<p>Name: ${order.shippingName}</p>
<p>Address: ${order.shippingAddress}</p>
<p>City: ${order.shippingCity}</p>
<p>State: ${order.shippingState}</p>
<p>ZIP: ${order.shippingZip}</p>
</div>
<table>
<tr>
<th>Title</th>
<th>Author</th>
<th>Price</th>
<th>Quantity</th>
<th>Subtotal</th>
</tr>
<c:forEach items="${order.orderItems}" var="item">
<tr>
<td>${item.book.title}</td>
<td>${item.book.author}</td>
<td>${item.price}</td>
<td>${item.quantity}</td>
<td><c:out value="${item.price.multiply(new
java.math.BigDecimal(item.quantity))}"/></td>
</tr>
</c:forEach>
</table>
<div class="total">
Total: $${order.totalAmount}
</div>
<a href="BookManagementServlet">Continue Shopping</a>
</div>
</body>
</html>
cart.jsp (Updated):
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>Shopping Cart</title>
140
Web Technologies Laboratory lll Year CSE C
<style>
table { border-collapse: collapse; width: 80%; margin: 20px auto; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.quantity-input { width: 50px; }
.update-button, .remove-button { padding: 5px; cursor: pointer; }
#cart-notification { position: fixed; top: 10px; right: 10px; background: #4CAF50; color: white;
padding: 10px; display: none; }
.total { font-weight: bold; margin: 20px; }
.checkout-button { display: block; width: 150px; margin: 10px auto; padding: 10px; text-align:
center; background: #4CAF50; color: white; text-decoration: none; }
</style>
</head>
<body>
<h2>Shopping Cart</h2>
<div id="cart-notification"></div>
<table id="cart-table">
<tr>
<th>Title</th>
<th>Author</th>
<th>Price</th>
<th>Quantity</th>
<th>Subtotal</th>
<th>Actions</th>
</tr>
<c:forEach items="${cart}" var="item">
<tr data-book-id="${item.book.id}">
<td>${item.book.title}</td>
<td>${item.book.author}</td>
<td>${item.book.price}</td>
<td>
<input type="number" class="quantity-input" value="${item.quantity}" min="1"
onchange="updateCart(${item.book.id}, this.value)">
</td>
<td class="subtotal">${item.subtotal}</td>
<td>
<button class="remove-button"
onclick="removeFromCart(${item.book.id})">Remove</button>
</td>
</tr>
</c:forEach>
</table>
<div class="total" id="cart-total">
Total: $<span id="total-amount"><c:out value="${cart.stream().map(item ->
item.subtotal).reduce(BigDecimal.ZERO, BigDecimal::add)}"/></span>
</div>
<a href="CheckoutServlet?action=review" class="checkout-button">Proceed to Checkout</a>
<a href="BookManagementServlet">Continue Shopping</a>
<script>
function updateCart(bookId, quantity) {
141
Web Technologies Laboratory lll Year CSE C
fetch('CartServlet', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `action=update&bookId=${bookId}&quantity=${quantity}`
})
.then(response => response.json())
.then(data => {
if (data.error) {
showNotification('Error: ' + data.error, 'red');
} else {
updateCartUI(data);
showNotification('Cart updated!', 'green');
}
})
.catch(error => showNotification('Error updating cart', 'red'));
}
function removeFromCart(bookId) {
fetch('CartServlet', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `action=remove&bookId=${bookId}`
})
.then(response => response.json())
.then(data => {
if (data.error) {
showNotification('Error: ' + data.error, 'red');
} else {
updateCartUI(data);
showNotification('Book removed from cart!', 'green');
}
})
.catch(error => showNotification('Error removing from cart', 'red'));
}
function updateCartUI(data) {
const table = document.getElementById('cart-table');
while (table.rows.length > 1) {
table.deleteRow(1);
}
data.cart.forEach(item => {
const row = table.insertRow();
row.setAttribute('data-book-id', item.bookId);
row.insertCell(0).textContent = item.title;
row.insertCell(1).textContent = item.author;
row.insertCell(2).textContent = item.price;
const quantityCell = row.insertCell(3);
quantityCell.innerHTML = `<input type="number" class="quantity-input"
value="${item.quantity}" min="1"
onchange="updateCart(${item.bookId}, this.value)">`;
row.insertCell(4).textContent = item.subtotal;
const actionCell = row.insertCell(5);
142
Web Technologies Laboratory lll Year CSE C
document.getElementById('total-amount').textContent = data.total;
}
function showNotification(message, color) {
const notification = document.getElementById('cart-notification');
notification.textContent = message;
notification.style.backgroundColor = color === 'green' ? '#4CAF50' : '#f44336';
notification.style.display = 'block';
setTimeout(() => notification.style.display = 'none', 3000);
}
</script>
</body>
</html>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.bookstore.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>BookManagementServlet</servlet-name>
<servlet-class>com.bookstore.BookManagementServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BookManagementServlet</servlet-name>
<url-pattern>/BookManagementServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CartServlet</servlet-name>
<servlet-class>com.bookstore.CartServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CartServlet</servlet-name>
<url-pattern>/CartServlet</url-pattern>
</servlet-mapping>
143
Web Technologies Laboratory lll Year CSE C
<servlet>
<servlet-name>CheckoutServlet</servlet-name>
<servlet-class>com.bookstore.CheckoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CheckoutServlet</servlet-name>
<url-pattern>/CheckoutServlet</url-pattern>
</servlet-mapping>
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>com.bookstore.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
144
Web Technologies Laboratory lll Year CSE C
│ │ └── views
│ │ ├── login.jsp
│ │ ├── welcome.jsp
│ │ ├── books.jsp
│ │ ├── book-form.jsp
│ │ ├── cart.jsp
│ │ ├── checkout.jsp
│ │ ├── order-confirmation.jsp
│ │ └── error.jsp
New Files:
o OrderDAO.java in com.bookstore.dao.
o Order.java, OrderItem.java in com.bookstore.entity.
o CheckoutServlet.java in com.bookstore.
o checkout.jsp, order-confirmation.jsp in WEB-INF/views.
145
Web Technologies Laboratory lll Year CSE C
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.4.0.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20230227</version>
</dependency>
</dependencies>
146
Web Technologies Laboratory lll Year CSE C
147
Web Technologies Laboratory lll Year CSE C
Output:
148