Lab 09 Cookie Session Lab
Lab 09 Cookie Session Lab
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
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 {
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);
request.getRequestDispatcher("/views/preferences.jsp").forward(request,
response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
<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>
<div class="navigation">
<a href="${pageContext.request.contextPath}/">Home</a> |
<a href="${pageContext.request.contextPath}/cart">Shopping
Cart</a>
</div>
</div>
</body>
</html>
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 {
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("welcomeMessage", welcomeMessage);
<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>
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-summary {
margin-top: 20px;
text-align: right;
font-weight: bold;
}
.cart-actions {
margin-top: 20px;
display: flex;
justify-content: space-between;
}
import java.io.Serializable;
import java.util.Objects;
public Product() {
}
@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);
}
}
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 {
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);
if (cart == null) {
cart = new ArrayList<>();
session.setAttribute("cart", cart);
}
request.setAttribute("cartTotal", total);
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
} else if ("update".equals(action)) {
// Update product quantities
String[] productIds = request.getParameterValues("productId");
String[] quantities = request.getParameterValues("quantity");
} else if ("remove".equals(action)) {
// Remove a product from the cart
int productId =
Integer.parseInt(request.getParameter("productId"));
} else if ("clear".equals(action)) {
// Clear the entire cart
cart.clear();
} else if ("checkout".equals(action)) {
// In a real application, this would process the order
// For this lab, we'll just simulate a successful checkout
<%
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>
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 {
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);
request.setAttribute("thankYouMessage", thankYouMessage);
<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>
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 {
@Override
public void sessionCreated(HttpSessionEvent se) {
HttpSession session = se.getSession();
ACTIVE_SESSIONS.incrementAndGet();
@Override
public void sessionDestroyed(HttpSessionEvent se) {
HttpSession session = se.getSession();
ACTIVE_SESSIONS.decrementAndGet();
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 {
@Override
public void destroy() {
// Cleanup code (if needed)
}
}
</web-app>
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 {
request.setAttribute("theme", theme);
// 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());
<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:
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