Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
15 views31 pages

Lab 09 Cookie Session Lab

This lab teaches the implementation and management of cookies and sessions in Java Servlets by creating a simple shopping cart application. Participants will learn to differentiate between cookies and sessions, manage user preferences, and apply best practices for security and performance. The lab includes setting up a project structure, creating servlets for user preferences and shopping cart functionality, and developing JSP pages for user interaction.

Uploaded by

nhanthuanphat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views31 pages

Lab 09 Cookie Session Lab

This lab teaches the implementation and management of cookies and sessions in Java Servlets by creating a simple shopping cart application. Participants will learn to differentiate between cookies and sessions, manage user preferences, and apply best practices for security and performance. The lab includes setting up a project structure, creating servlets for user preferences and shopping cart functionality, and developing JSP pages for user interaction.

Uploaded by

nhanthuanphat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 31

Lab - Cookies and Sessions with Java Servlets

Overview
In this lab, you will learn how to implement and manage cookies and sessions in a web
application using Java Servlets with JDK 21. You will create a simple shopping cart
application that demonstrates the use of both cookies and sessions for maintaining state
in web applications.

Learning Objectives
• Understand the difference between cookies and sessions
• Implement cookie-based user preferences
• Create and manage session data
• Build a functional shopping cart using session tracking
• Apply best practices for security and performance

Prerequisites
• JDK 21 installed
• Apache Tomcat 10.x or Jakarta EE 10 compatible server
• IDE (Eclipse, IntelliJ IDEA, or VS Code with Java extensions)
• Basic knowledge of HTML and Java Servlets

Project Setup
Step 1: Create a new Dynamic Web Project
1. Open your IDE and create a new Dynamic Web Project named CookieSessionLab
2. Ensure the project is configured to use JDK 21
3. Configure your project to use Jakarta EE 10 or newer
4. Set up Apache Tomcat 10.x as your runtime environment

Step 2: Project Structure


Create the following directory structure:
CookieSessionLab/
├── src/
│ └── main/
│ ├── java/
│ │ └── com/
│ │ └── weblab/
│ │ ├── controller/
│ │ ├── model/
│ │ └── util/
│ └── webapp/
│ ├── WEB-INF/
│ │ ├── lib/
│ │ └── web.xml
│ ├── css/
│ ├── js/
│ └── views/

Part 1: Working with Cookies


Step 3: Create User Preferences with Cookies
Create a new servlet that will handle user preferences using cookies:
UserPreferencesServlet.java
package com.weblab.controller;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/preferences")
public class UserPreferencesServlet extends HttpServlet {

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

// Read existing cookies (if any)


Cookie[] cookies = request.getCookies();
String theme = "light"; // Default theme
String language = "en"; // Default language

if (cookies != null) {
for (Cookie cookie : cookies) {
if ("theme".equals(cookie.getName())) {
theme = cookie.getValue();
} else if ("language".equals(cookie.getName())) {
language = cookie.getValue();
}
}
}
// Set attributes to display current preferences
request.setAttribute("currentTheme", theme);
request.setAttribute("currentLanguage", language);

// Forward to the preferences page

request.getRequestDispatcher("/views/preferences.jsp").forward(request,
response);
}

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

// Get user's selected preferences


String theme = request.getParameter("theme");
String language = request.getParameter("language");

// Create cookies for theme


Cookie themeCookie = new Cookie("theme", theme);
themeCookie.setMaxAge(60 * 60 * 24 * 30); // 30 days
themeCookie.setPath("/");
response.addCookie(themeCookie);

// Create cookies for language


Cookie languageCookie = new Cookie("language", language);
languageCookie.setMaxAge(60 * 60 * 24 * 30); // 30 days
languageCookie.setPath("/");
response.addCookie(languageCookie);

// Redirect back to the preferences page


response.sendRedirect(request.getContextPath() +
"/preferences?updated=true");
}
}

Step 4: Create the Preferences JSP


Create a new JSP file at /webapp/views/preferences.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>User Preferences</title>
<link rel="stylesheet"
href="${pageContext.request.contextPath}/css/styles.css">
</head>
<body class="${currentTheme}">
<div class="container">
<h1>User Preferences</h1>

<% if (request.getParameter("updated") != null) { %>


<div class="alert alert-success">
Your preferences have been updated successfully!
</div>
<% } %>

<form action="${pageContext.request.contextPath}/preferences"
method="post">
<div class="form-group">
<label for="theme">Theme:</label>
<select name="theme" id="theme" class="form-control">
<option value="light" ${currentTheme == 'light' ?
'selected' : ''}>Light</option>
<option value="dark" ${currentTheme == 'dark' ?
'selected' : ''}>Dark</option>
<option value="blue" ${currentTheme == 'blue' ?
'selected' : ''}>Blue</option>
</select>
</div>

<div class="form-group">
<label for="language">Language:</label>
<select name="language" id="language" class="form-control">
<option value="en" ${currentLanguage == 'en' ? 'selected'
: ''}>English</option>
<option value="fr" ${currentLanguage == 'fr' ? 'selected'
: ''}>French</option>
<option value="es" ${currentLanguage == 'es' ? 'selected'
: ''}>Spanish</option>
<option value="vi" ${currentLanguage == 'vi' ? 'selected'
: ''}>Vietnamese</option>
</select>
</div>

<button type="submit" class="btn btn-primary">Save


Preferences</button>
</form>

<div class="navigation">
<a href="${pageContext.request.contextPath}/">Home</a> |
<a href="${pageContext.request.contextPath}/cart">Shopping
Cart</a>
</div>
</div>
</body>
</html>

Step 5: Create a Home Page with Cookie-based Customization


Create a new servlet to handle the home page:
HomeServlet.java
package com.weblab.controller;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/")
public class HomeServlet extends HttpServlet {

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

// Read existing cookies (if any)


Cookie[] cookies = request.getCookies();
String theme = "light"; // Default theme
String language = "en"; // Default language

if (cookies != null) {
for (Cookie cookie : cookies) {
if ("theme".equals(cookie.getName())) {
theme = cookie.getValue();
} else if ("language".equals(cookie.getName())) {
language = cookie.getValue();
}
}
}

// Set attributes for the page


request.setAttribute("theme", theme);
request.setAttribute("language", language);

// Set welcome message based on language


String welcomeMessage;
switch (language) {
case "fr":
welcomeMessage = "Bienvenue à notre magasin en ligne!";
break;
case "es":
welcomeMessage = "¡Bienvenido a nuestra tienda en línea!";
break;
case "vi":
welcomeMessage = "Chào mừng đến với cửa hàng trực tuyến của
chúng tôi!";
break;
default:
welcomeMessage = "Welcome to our online store!";
}

request.setAttribute("welcomeMessage", welcomeMessage);

// Forward to the home page


request.getRequestDispatcher("/views/home.jsp").forward(request,
response);
}
}

Create a home page JSP at /webapp/views/home.jsp:


<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Online Store</title>
<link rel="stylesheet"
href="${pageContext.request.contextPath}/css/styles.css">
</head>
<body class="${theme}">
<div class="container">
<h1>${welcomeMessage}</h1>

<div class="product-grid">
<div class="product">
<img
src="${pageContext.request.contextPath}/images/product1.jpg" alt="Product 1">
<h3>Laptop</h3>
<p>$999.99</p>
<form action="${pageContext.request.contextPath}/cart"
method="post">
<input type="hidden" name="action" value="add">
<input type="hidden" name="productId" value="1">
<input type="hidden" name="productName" value="Laptop">
<input type="hidden" name="productPrice" value="999.99">
<button type="submit" class="btn btn-primary">Add to
Cart</button>
</form>
</div>

<div class="product">
<img
src="${pageContext.request.contextPath}/images/product2.jpg" alt="Product 2">
<h3>Smartphone</h3>
<p>$699.99</p>
<form action="${pageContext.request.contextPath}/cart"
method="post">
<input type="hidden" name="action" value="add">
<input type="hidden" name="productId" value="2">
<input type="hidden" name="productName"
value="Smartphone">
<input type="hidden" name="productPrice" value="699.99">
<button type="submit" class="btn btn-primary">Add to
Cart</button>
</form>
</div>

<div class="product">
<img
src="${pageContext.request.contextPath}/images/product3.jpg" alt="Product 3">
<h3>Headphones</h3>
<p>$149.99</p>
<form action="${pageContext.request.contextPath}/cart"
method="post">
<input type="hidden" name="action" value="add">
<input type="hidden" name="productId" value="3">
<input type="hidden" name="productName"
value="Headphones">
<input type="hidden" name="productPrice" value="149.99">
<button type="submit" class="btn btn-primary">Add to
Cart</button>
</form>
</div>
</div>

<div class="navigation">
<a href="${pageContext.request.contextPath}/preferences">User
Preferences</a> |
<a href="${pageContext.request.contextPath}/cart">Shopping
Cart</a>
</div>
</div>
</body>
</html>

Step 6: Create a CSS file for styling


Create a new CSS file at /webapp/css/styles.css:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}

body {
font-family: Arial, sans-serif;
line-height: 1.6;
padding: 20px;
}

/* Theme Classes */
body.light {
background-color: #f8f9fa;
color: #333;
}

body.dark {
background-color: #333;
color: #f8f9fa;
}

body.blue {
background-color: #e6f7ff;
color: #005b96;
}

.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}

h1 {
margin-bottom: 20px;
text-align: center;
}

.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
}

.form-control {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}

.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
}

.btn-primary {
background-color: #007bff;
color: white;
}

.alert {
padding: 15px;
margin-bottom: 20px;
border-radius: 4px;
}

.alert-success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}

.navigation {
margin-top: 30px;
text-align: center;
}

.navigation a {
margin: 0 10px;
text-decoration: none;
}

body.light .navigation a {
color: #007bff;
}

body.dark .navigation a {
color: #4dabf7;
}

body.blue .navigation a {
color: #0056b3;
}

/* Product Grid */
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
margin-top: 20px;
}

.product {
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
text-align: center;
}

body.dark .product {
border-color: #555;
}

.product img {
max-width: 100%;
height: auto;
margin-bottom: 10px;
}

.product h3 {
margin-bottom: 5px;
}

.product p {
margin-bottom: 10px;
font-weight: bold;
}

/* Cart Table */
.cart-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}

.cart-table th, .cart-table td {


padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}

body.dark .cart-table th, body.dark .cart-table td {


border-color: #555;
}

.cart-summary {
margin-top: 20px;
text-align: right;
font-weight: bold;
}

.cart-actions {
margin-top: 20px;
display: flex;
justify-content: space-between;
}

Part 2: Working with Sessions


Step 7: Create a Product Model Class
Create a product model class:
Product.java
package com.weblab.model;

import java.io.Serializable;
import java.util.Objects;

public class Product implements Serializable {


private static final long serialVersionUID = 1L;

private int id;


private String name;
private double price;
private int quantity;

public Product() {
}

public Product(int id, String name, double price) {


this.id = id;
this.name = name;
this.price = price;
this.quantity = 1;
}

public int getId() {


return id;
}

public void setId(int id) {


this.id = id;
}

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}

public double getPrice() {


return price;
}

public void setPrice(double price) {


this.price = price;
}

public int getQuantity() {


return quantity;
}

public void setQuantity(int quantity) {


this.quantity = quantity;
}

public void incrementQuantity() {


this.quantity++;
}

public void decrementQuantity() {


if (this.quantity > 0) {
this.quantity--;
}
}
public double getSubtotal() {
return this.price * this.quantity;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Product product = (Product) o;
return id == product.id;
}

@Override
public int hashCode() {
return Objects.hash(id);
}
}

Step 8: Create a Shopping Cart Servlet


Create a servlet to handle shopping cart operations:
CartServlet.java
package com.weblab.controller;

import com.weblab.model.Product;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
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.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@WebServlet("/cart")
public class CartServlet extends HttpServlet {

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

// Get current theme and language from cookies


Cookie[] cookies = request.getCookies();
String theme = "light";
String language = "en";

if (cookies != null) {
for (Cookie cookie : cookies) {
if ("theme".equals(cookie.getName())) {
theme = cookie.getValue();
} else if ("language".equals(cookie.getName())) {
language = cookie.getValue();
}
}
}

request.setAttribute("theme", theme);
request.setAttribute("language", language);

// Get the shopping cart from session or create a new one


HttpSession session = request.getSession();
List<Product> cart = (List<Product>) session.getAttribute("cart");

if (cart == null) {
cart = new ArrayList<>();
session.setAttribute("cart", cart);
}

// Calculate cart total


double total = 0.0;
for (Product product : cart) {
total += product.getSubtotal();
}

request.setAttribute("cartTotal", total);

// Forward to the cart page


request.getRequestDispatcher("/views/cart.jsp").forward(request,
response);
}

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

// Get the action parameter


String action = request.getParameter("action");

// Get the session and cart


HttpSession session = request.getSession();
List<Product> cart = (List<Product>) session.getAttribute("cart");
if (cart == null) {
cart = new ArrayList<>();
session.setAttribute("cart", cart);
}

// Handle different actions


if ("add".equals(action)) {
// Add a product to the cart
int productId =
Integer.parseInt(request.getParameter("productId"));
String productName = request.getParameter("productName");
double productPrice =
Double.parseDouble(request.getParameter("productPrice"));

// Check if the product is already in the cart


boolean found = false;
for (Product product : cart) {
if (product.getId() == productId) {
product.incrementQuantity();
found = true;
break;
}
}

// If not found, add a new product


if (!found) {
Product newProduct = new Product(productId, productName,
productPrice);
cart.add(newProduct);
}

// Update the session


session.setAttribute("cart", cart);

// Redirect to cart page


response.sendRedirect(request.getContextPath() + "/cart");

} else if ("update".equals(action)) {
// Update product quantities
String[] productIds = request.getParameterValues("productId");
String[] quantities = request.getParameterValues("quantity");

if (productIds != null && quantities != null && productIds.length


== quantities.length) {
for (int i = 0; i < productIds.length; i++) {
int id = Integer.parseInt(productIds[i]);
int quantity = Integer.parseInt(quantities[i]);
// Update quantity for this product
for (Product product : cart) {
if (product.getId() == id) {
product.setQuantity(quantity);
break;
}
}
}

// Remove products with quantity 0


cart.removeIf(product -> product.getQuantity() <= 0);

// Update the session


session.setAttribute("cart", cart);
}

// Redirect to cart page


response.sendRedirect(request.getContextPath() + "/cart");

} else if ("remove".equals(action)) {
// Remove a product from the cart
int productId =
Integer.parseInt(request.getParameter("productId"));

// Find and remove the product


Iterator<Product> iterator = cart.iterator();
while (iterator.hasNext()) {
Product product = iterator.next();
if (product.getId() == productId) {
iterator.remove();
break;
}
}

// Update the session


session.setAttribute("cart", cart);

// Redirect to cart page


response.sendRedirect(request.getContextPath() + "/cart");

} else if ("clear".equals(action)) {
// Clear the entire cart
cart.clear();

// Update the session


session.setAttribute("cart", cart);

// Redirect to cart page


response.sendRedirect(request.getContextPath() + "/cart");

} else if ("checkout".equals(action)) {
// In a real application, this would process the order
// For this lab, we'll just simulate a successful checkout

// Clear the cart


cart.clear();
session.setAttribute("cart", cart);

// Set a "checkout success" attribute in session


session.setAttribute("checkoutSuccess", true);

// Redirect to a checkout success page


response.sendRedirect(request.getContextPath() + "/checkout-
success");
}
}
}

Step 9: Create a Cart JSP Page


Create a JSP page for the shopping cart at /webapp/views/cart.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.List" %>
<%@ page import="com.weblab.model.Product" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Shopping Cart</title>
<link rel="stylesheet"
href="${pageContext.request.contextPath}/css/styles.css">
</head>
<body class="${theme}">
<div class="container">
<h1>Shopping Cart</h1>

<%
List<Product> cart = (List<Product>) session.getAttribute("cart");
if (cart == null || cart.isEmpty()) {
%>
<p>Your cart is empty.</p>
<%
} else {
%>
<form action="${pageContext.request.contextPath}/cart"
method="post">
<input type="hidden" name="action" value="update">

<table class="cart-table">
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Quantity</th>
<th>Subtotal</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<%
for (Product product : cart) {
%>
<tr>
<td><%= product.getName() %></td>
<td>$<%= String.format("%.2f",
product.getPrice()) %></td>
<td>
<input type="hidden" name="productId"
value="<%= product.getId() %>">
<input type="number" name="quantity"
value="<%= product.getQuantity() %>" min="0" class="form-control"
style="width: 60px;">
</td>
<td>$<%= String.format("%.2f",
product.getSubtotal()) %></td>
<td>
<a
href="${pageContext.request.contextPath}/cart?action=remove&productId=<%=
product.getId() %>"

onclick="document.getElementById('removeForm<%= product.getId()
%>').submit(); return false;">Remove</a>
<form id="removeForm<%= product.getId()
%>" action="${pageContext.request.contextPath}/cart" method="post"
style="display:none;">
<input type="hidden" name="action"
value="remove">
<input type="hidden" name="productId"
value="<%= product.getId() %>">
</form>
</td>
</tr>
<%
}
%>
</tbody>
</table>

<div class="cart-summary">
Total: $<%= String.format("%.2f", (Double)
request.getAttribute("cartTotal")) %>
</div>

<div class="cart-actions">
<button type="submit" class="btn btn-primary">Update
Cart</button>

<div>
<a href="#"
onclick="document.getElementById('clearForm').submit(); return false;"
class="btn btn-secondary">Clear Cart</a>
<a href="#"
onclick="document.getElementById('checkoutForm').submit(); return false;"
class="btn btn-success">Checkout</a>
</div>
</div>
</form>

<form id="clearForm"
action="${pageContext.request.contextPath}/cart" method="post">
<input type="hidden" name="action" value="clear">
</form>

<form id="checkoutForm"
action="${pageContext.request.contextPath}/cart" method="post">
<input type="hidden" name="action" value="checkout">
</form>
<%
}
%>

<div class="navigation">
<a href="${pageContext.request.contextPath}/">Continue
Shopping</a> |
<a href="${pageContext.request.contextPath}/preferences">User
Preferences</a>
</div>
</div>
</body>
</html>

Step 10: Create a Checkout Success Servlet and Page


Create a servlet for the checkout success page:
CheckoutSuccessServlet.java
package com.weblab.controller;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/checkout-success")
public class CheckoutSuccessServlet extends HttpServlet {

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

// Get current theme and language from cookies


Cookie[] cookies = request.getCookies();
String theme = "light";
String language = "en";

if (cookies != null) {
for (Cookie cookie : cookies) {
if ("theme".equals(cookie.getName())) {
theme = cookie.getValue();
} else if ("language".equals(cookie.getName())) {
language = cookie.getValue();
}
}
}

request.setAttribute("theme", theme);
request.setAttribute("language", language);

// Check if the checkout was successful


HttpSession session = request.getSession();
Boolean checkoutSuccess = (Boolean)
session.getAttribute("checkoutSuccess");

if (checkoutSuccess == null || !checkoutSuccess) {


// If not, redirect to the home page
response.sendRedirect(request.getContextPath() + "/");
return;
}
// Reset the checkout success flag
session.removeAttribute("checkoutSuccess");

// Set thank you message based on language


String thankYouMessage;
switch (language) {
case "fr":
thankYouMessage = "Merci pour votre commande!";
break;
case "es":
thankYouMessage = "¡Gracias por su pedido!";
break;
case "vi":
thankYouMessage = "Cảm ơn bạn đã đặt hàng!";
break;
default:
thankYouMessage = "Thank you for your order!";
}

request.setAttribute("thankYouMessage", thankYouMessage);

// Forward to the success page


request.getRequestDispatcher("/views/checkout-
success.jsp").forward(request, response);
}
}

Create a JSP for the checkout success page at /webapp/views/checkout-success.jsp:


<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Checkout Success</title>
<link rel="stylesheet"
href="${pageContext.request.contextPath}/css/styles.css">
</head>
<body class="${theme}">
<div class="container">
<h1>${thankYouMessage}</h1>

<div class="checkout-success">
<p>Your order has been successfully processed.</p>
<p>Order number: ORD-<%= System.currentTimeMillis() %></p>
<p>A confirmation email has been sent to your email address.</p>
</div>
<div class="navigation">
<a href="${pageContext.request.contextPath}/">Continue
Shopping</a> |
<a href="${pageContext.request.contextPath}/preferences">User
Preferences</a>
</div>
</div>
</body>
</html>

Part 3: Session Management and Security


Step 11: Create a Session Listener
Create a session listener class to track session creation and destruction:
SessionListener.java
package com.weblab.util;

import jakarta.servlet.annotation.WebListener;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;

@WebListener
public class SessionListener implements HttpSessionListener {

private static final Logger LOGGER =


Logger.getLogger(SessionListener.class.getName());
private static final AtomicInteger ACTIVE_SESSIONS = new AtomicInteger();

@Override
public void sessionCreated(HttpSessionEvent se) {
HttpSession session = se.getSession();
ACTIVE_SESSIONS.incrementAndGet();

LOGGER.info("Session created: " + session.getId());


LOGGER.info("Total active sessions: " + ACTIVE_SESSIONS.get());

// Set session timeout (in seconds)


session.setMaxInactiveInterval(1800); // 30 minutes
}

@Override
public void sessionDestroyed(HttpSessionEvent se) {
HttpSession session = se.getSession();
ACTIVE_SESSIONS.decrementAndGet();

LOGGER.info("Session destroyed: " + session.getId());


LOGGER.info("Total active sessions: " + ACTIVE_SESSIONS.get());
}

public static int getActiveSessions() {


return ACTIVE_SESSIONS.get();
}
}

Step 12: Create a Session Filter for Security


Create a filter to add security headers and manage session-related tasks:
SessionSecurityFilter.java
package com.weblab.util;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;

@WebFilter("/*")
public class SessionSecurityFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Initialization code (if needed)
}

@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {

HttpServletRequest httpRequest = (HttpServletRequest) request;


HttpServletResponse httpResponse = (HttpServletResponse) response;

// Add security headers


httpResponse.setHeader("X-XSS-Protection", "1; mode=block");
httpResponse.setHeader("X-Content-Type-Options", "nosniff");
httpResponse.setHeader("X-Frame-Options", "DENY");
httpResponse.setHeader("Cache-Control", "no-store, no-cache, must-
revalidate, max-age=0");
httpResponse.setHeader("Pragma", "no-cache");

// Log request information (for demonstration purposes)


String requestURI = httpRequest.getRequestURI();
String remoteAddr = httpRequest.getRemoteAddr();
HttpSession session = httpRequest.getSession(false);
String sessionId = (session != null) ? session.getId() : "None";

System.out.println("Request URI: " + requestURI);


System.out.println("Remote Address: " + remoteAddr);
System.out.println("Session ID: " + sessionId);

// Continue the filter chain


chain.doFilter(request, response);
}

@Override
public void destroy() {
// Cleanup code (if needed)
}
}

Step 13: Update the web.xml Configuration


Update the web.xml file to include session configuration:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">

<display-name>Cookie Session Lab</display-name>

<!-- Session Configuration -->


<session-config>
<session-timeout>30</session-timeout> <!-- 30 minutes -->
<cookie-config>
<http-only>true</http-only> <!-- Prevents JavaScript from
accessing the cookie -->
<secure>true</secure> <!-- Ensures cookie is sent only
over HTTPS -->
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>

<!-- Error Pages -->


<error-page>
<error-code>404</error-code>
<location>/views/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/views/error/500.jsp</location>
</error-page>

</web-app>

Step 14: Create a Session Information Servlet


Create a servlet to display session information for educational purposes:
SessionInfoServlet.java
package com.weblab.controller;

import com.weblab.util.SessionListener;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
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.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

@WebServlet("/session-info")
public class SessionInfoServlet extends HttpServlet {

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

// Get theme from cookies


Cookie[] cookies = request.getCookies();
String theme = "light";
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("theme".equals(cookie.getName())) {
theme = cookie.getValue();
break;
}
}
}

request.setAttribute("theme", theme);

// Get current session or create a new one


HttpSession session = request.getSession();

// Session information
Map<String, Object> sessionInfo = new HashMap<>();
sessionInfo.put("id", session.getId());
sessionInfo.put("creationTime", new Date(session.getCreationTime()));
sessionInfo.put("lastAccessedTime", new
Date(session.getLastAccessedTime()));
sessionInfo.put("maxInactiveInterval",
session.getMaxInactiveInterval() + " seconds");
sessionInfo.put("new", session.isNew());

// Active sessions count


sessionInfo.put("activeSessions",
SessionListener.getActiveSessions());

// Get all session attributes


Map<String, Object> sessionAttributes = new HashMap<>();
Enumeration<String> attributeNames = session.getAttributeNames();
while (attributeNames.hasMoreElements()) {
String name = attributeNames.nextElement();
Object value = session.getAttribute(name);
sessionAttributes.put(name, value.toString());
}

// Get all cookies


Map<String, String> cookieMap = new HashMap<>();
if (cookies != null) {
for (Cookie cookie : cookies) {
cookieMap.put(cookie.getName(), cookie.getValue() + " (Max
Age: " + cookie.getMaxAge() + ")");
}
}

// Set attributes for the view


request.setAttribute("sessionInfo", sessionInfo);
request.setAttribute("sessionAttributes", sessionAttributes);
request.setAttribute("cookies", cookieMap);

// Forward to the view


request.getRequestDispatcher("/views/session-
info.jsp").forward(request, response);
}
}

Create a JSP page for session information at /webapp/views/session-info.jsp:


<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.Map" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Session Information</title>
<link rel="stylesheet"
href="${pageContext.request.contextPath}/css/styles.css">
</head>
<body class="${theme}">
<div class="container">
<h1>Session Information</h1>

<h2>Basic Session Info</h2>


<table class="cart-table">
<thead>
<tr>
<th>Property</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<%
Map<String, Object> sessionInfo = (Map<String, Object>)
request.getAttribute("sessionInfo");
for (Map.Entry<String, Object> entry :
sessionInfo.entrySet()) {
%>
<tr>
<td><strong><%= entry.getKey() %></strong></td>
<td><%= entry.getValue() %></td>
</tr>
<%
}
%>
</tbody>
</table>
<h2>Session Attributes</h2>
<%
Map<String, Object> sessionAttributes = (Map<String, Object>)
request.getAttribute("sessionAttributes");
if (sessionAttributes.isEmpty()) {
%>
<p>No session attributes found.</p>
<%
} else {
%>
<table class="cart-table">
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<%
for (Map.Entry<String, Object> entry :
sessionAttributes.entrySet()) {
%>
<tr>
<td><strong><%= entry.getKey() %></strong></td>
<td><%= entry.getValue() %></td>
</tr>
<%
}
%>
</tbody>
</table>
<%
}
%>

<h2>Cookies</h2>
<%
Map<String, String> cookies = (Map<String, String>)
request.getAttribute("cookies");
if (cookies.isEmpty()) {
%>
<p>No cookies found.</p>
<%
} else {
%>
<table class="cart-table">
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<%
for (Map.Entry<String, String> entry :
cookies.entrySet()) {
%>
<tr>
<td><strong><%= entry.getKey() %></strong></td>
<td><%= entry.getValue() %></td>
</tr>
<%
}
%>
</tbody>
</table>
<%
}
%>

<div class="navigation">
<a href="${pageContext.request.contextPath}/">Home</a> |
<a href="${pageContext.request.contextPath}/cart">Shopping
Cart</a> |
<a href="${pageContext.request.contextPath}/preferences">User
Preferences</a>
</div>
</div>
</body>
</html>

Lab Tasks
Now that you have set up the project, complete the following tasks:

Task 1: Understanding Cookies


1. Run the application and navigate to the User Preferences page.
2. Change the theme and language settings.
3. Observe how the preferences persist across page refreshes and when navigating to
different pages.
4. Use browser developer tools to examine the cookies created by the application.
5. Delete the cookies and observe what happens when you refresh the page.

Task 2: Exploring Session Management


1. Add products to your shopping cart.
2. Navigate to the Session Info page to see what information is stored in your session.
3. Open a new browser or use incognito/private mode to see that the shopping cart is
empty (new session).
4. Observe how the cart persists when navigating between pages in the same browser
session.
5. Wait for the session timeout (set to 30 minutes by default) or close and reopen the
browser to see the session expire.

Task 3: Modifying the Application


1. Add a new product page that allows users to view product details before adding to
cart.
2. Implement a feature that allows users to save their cart for later using cookies.
3. Create a login system using sessions to track authenticated users.
4. Implement a “Recently Viewed Products” feature using cookies to track browsing
history.

Task 4: Security Analysis


1. Analyze the session security measures implemented in the application.
2. Identify potential security vulnerabilities related to cookies and sessions.
3. Implement cross-site request forgery (CSRF) protection for form submissions.
4. Modify the application to use secure cookies only.

Deliverables
1. Complete source code for the application with all tasks implemented.
2. A brief report (1-2 pages) describing:
o How cookies and sessions are implemented in the application
o The differences between cookies and sessions
o Security considerations when using cookies and sessions
o Your implementation of the tasks and any challenges faced

Grading Criteria
• Functionality (50%): All features work as expected.
• Understanding (25%): Demonstrated understanding of cookies and sessions in the
report.
• Code Quality (15%): Well-organized, commented, and maintainable code.
• Security (10%): Implementation of security best practices.

Submission
Submit a zip file containing your project and report to the course submission system by the
deadline.
Additional Resources
• Jakarta Servlet Specification
• JDK 21 Documentation
• Apache Tomcat Documentation
• OWASP Session Management Cheat Sheet

You might also like