1. Add JSTL Library to Maven

Open your pom.xml and add this dependency:

1
2
3
4
5
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>jakarta.servlet.jsp.jstl</artifactId>
    <version>2.0.0</version>
</dependency>

After running build with dependences.

2. Import JSTL in Your JSP

1
2
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

EL Scopes in JSTL: Expression Language (EL) automatically handles attributes across different scopes:

3. Example: Replace Scriptlets with JSTL + EL

1
2
3
4
<%
    <h2>Welcome, ${username} (Cookie Based)</h2>
%>

replace to:

1
2
3
4
5
6
7
8
9
10
11
12
13
<c:if test="${not empty username}">
    <h2>Welcome, ${username} (Cookie Based)</h2>
    
    <form action="${pageContext.request.contextPath}/logout" method="post">
        <button type="submit" class="btn btn-outline-primary">Logout</button>
    </form>
</c:if>

<!-- Show message if user not logged in -->
<c:if test="${empty username}">
    <h2 class="text-danger">You are not logged in.</h2>
    <a href="${pageContext.request.contextPath}/login" class="btn btn-primary">Login</a>
</c:if>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Product {
    private String name;
    private double price;
    
    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    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;
    }
}
1
2
3
4
5
6
7
8
9
    // Fake product list
    List<Product> products = new ArrayList<>();
    products.add(new Product("Laptop", 1200));
    products.add(new Product("Phone", 800));
    products.add(new Product("Headset", 150));
    
    request.setAttribute("products", products);

    request.getRequestDispatcher("/views/pages/home.jsp").forward(request, response);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!-- ... -->
<hr/>
<h3>Available Products</h3>
<c:choose>
    <c:when test="${not empty requestScope.products}">
        <table class="table table-bordered">
            <thead>
                <tr>
                    <th>#</th>
                    <th>Name</th>
                    <th>Price</th>
                </tr>
            </thead>
            <tbody>
                <c:forEach var="p" items="${products}" varStatus="status">
                    <tr>
                        <td>${status.index + 1}</td>
                        <td>${p.name}</td>
                        <td><fmt:formatNumber value="${p.price}" type="currency" currencySymbol="$" /></td>
                    </tr>
                </c:forEach>
            </tbody>
        </table>
    </c:when>
    <c:otherwise>
        <p class="text-muted">No products available at the moment.</p>
    </c:otherwise>
</c:choose>