Practical Implementation of JSP, EL Expressions and JSTL Tag Library for Java Web Development

JSP Core Directives

JSP directives control how the JSP engine parses and compiles the current page. There are 3 standard directive types:

Page Directive

Configures page-level properties, syntax reference:

<%@ page 
  language="java" 
  import="java.util.*,com.example.entity.Employee"
  pageEncoding="UTF-8"
  session="true"
  buffer="16kb"
  errorPage="/error/exception.jsp"
  isELIgnored="false"
%>

Common attributes:

  1. language: Fixed value java for standard JSP implementations, specifies the scripting language for scriptlets.
  2. import: Declares Java class dependencies, multiple packages are separated by commas.
  3. session: Defaults to true, automatically creates an HttpSession object for the current request if no existing session is found.
  4. buffer: Sets the size of the JspWriter output buffer, default value is 8kb. Output content is flushed to the browser only when the buffer is full or page rendering completes.
  5. errorPage: Defines the redirect target when an uncaught exception occurs on the current page for page-level exception handling.
  6. isErrorPage: Set to true on exception handling pages to expose the built-in exception object for error detail retrieval.
  7. isELIgnored: Defaults to false, enables EL expression parsing when set to false.

Global exception handling is configured in web.xml, with higher priority than page-level errorPage for matching error codes or exception types:

<!-- Handle 500 internal server error -->
<error-page>
  <error-code>500</error-code>
  <location>/WEB-INF/errors/500.jsp</location>
</error-page>
<!-- Handle specific arithmetic exception type -->
<error-page>
  <error-type>java.lang.ArithmeticException</error-type>
  <location>/WEB-INF/errors/math_error.jsp</location>
</error-page>

Include Directive

Implements static content inclusion at compile time. The content of the target file is merged into the current JSP's generated Servlet code during translation:

<%@ include file="/common/navbar.jsp" %>

Static inclusion is recommended for reusable static fragments (headers, footers, navigation bars) to avoid repeated compilation of shared content.

Taglib Directive

Imports custom or standard tag libraries to reduce embedded Java code in JSP pages:

<!-- Import JSTL core tag library -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!-- Import JSTL function tag library -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

The prefix attribute defines the namespace alias used to call tags from the imported library.

JSP 9 Built-in Implicit Objects

These objects are automatically instantiated by the JSP engine and can be used directly in scriptlets without explicit declaration:

JSP Object Name Corresponding Servlet Type Scope
request HttpServletRequest Request
response HttpServletResponse Page
session HttpSession Session
application ServletContext Application
config ServletConfig Page
out JspWriter Page
exception Throwable Page (only available on pages with isErrorPage=true)
page Object (current Servlet instance) Page
pageContext PageContext Page

Key features of pageContext:

  1. Wraps all other implicit objects, can retrieve any other built-in object via corresponding getter methods.
  2. Supports data storage and retrieval across all 4 scope levels (page, request, session, application).
  3. The findAttribute(String key) method searches for matching attributes in order: page → request → session → application, returns null if no match is found.

Example usage of implicit objects:

<%@ page language="java" pageEncoding="UTF-8" %>
<html>
<body>
  Request parameter username: <%= request.getParameter("username") %><br/>
  <% 
    session.setAttribute("loginUser", "li_ming");
    application.setAttribute("siteVisitCount", 12450);
  %>
  Logged in user: <%= session.getAttribute("loginUser") %><br/>
  Total site visits: <%= application.getAttribute("siteVisitCount") %>
</body>
</html>

Difference between JspWriter (out) and PrintWriter (from response.getWriter()):

  • Content written to out is first stored in the JSP output buffer, then flushed to the PrintWriter buffer before being sent to the browser.
  • Content written directly to PrintWriter bypasses the JSP buffer and is sent to the client immediately.

EL Expression Syntax

EL (Expression Language) simplifies retrieval of domain attribute values and basic computation, with syntax ${expression}. If no matching attribute is found, EL returns an empty string instead of null.

EL Built-in Objects

  1. Scope-related: pageScope, requestScope, sessionScope, applicationScope (retrieve attributes from specified scopes)
  2. Request parameter: param (single parameter), paramValues (array of parameters for multi-value fields)
  3. Request header: header (single header), headerValues (array of header values)
  4. cookie: Retrieve cookie name and value pairs
  5. initParam: Retrieve context initialization parameters configured in web.xml
  6. pageContext: Access the current PageContext object, commonly used to get the web application context path: ${pageContext.request.contextPath}

EL Usage Examples

<%@ page language="java" import="java.util.*,com.example.entity.Employee" pageEncoding="UTF-8" %>
<%
  // Store simple string in page scope
  pageContext.setAttribute("deptName", "R&D Department");
  // Store custom object in request scope
  Employee emp = new Employee(1001, "wang_hua", 18000.0);
  request.setAttribute("empInfo", emp);
  // Store list in session scope
  List<String> fruitList = new ArrayList<>();
  fruitList.add("apple");
  fruitList.add("banana");
  fruitList.add("orange");
  session.setAttribute("fruitInventory", fruitList);
  // Store map in application scope
  Map<String, Integer> salaryMap = new HashMap<>();
  salaryMap.put("li_ming", 22000);
  salaryMap.put("wang_hua", 18000);
  application.setAttribute("deptSalary", salaryMap);
%>
Department name: ${deptName}<br/>
Employee ID: ${empInfo.empId} | Name: ${empInfo.empName} | Salary: ${empInfo.salary}<br/>
Second fruit in inventory: ${fruitInventory[1]}<br/>
Li Ming's salary: ${deptSalary['li_ming']}<br/>
Web app context path: ${pageContext.request.contextPath}

EL Operators

  1. Arithmetic operators: +, -, *, / (or div), % (or mod)
  2. Comparison operators: == (or eq), != (or ne), < (or lt), > (or gt), <= (or le), >= (or ge)
  3. Logical operators: && (or and), || (or or), ! (or not)
  4. Empty check operator: empty (returns true for null, empty string, empty collection, empty array)
  5. Ternary operator: ${condition ? valueIfTrue : valueIfFalse}

Example of ternary operator usage for form dropdown selection:

<%@ page language="java" pageEncoding="UTF-8" %>
<% pageContext.setAttribute("gender", "female"); %>
<select name="gender">
  <option value="">Please select</option>
  <option value="male" ${gender == 'male' ? 'selected' : ''}>Male</option>
  <option value="female" ${gender == 'female' ? 'selected' : ''}>Female</option>
</select>

JSTL Core Tag Library (prefix c)

c:set Tag

Stores data in specified scope, or sets properties of existing domain objects:

<!-- Store string in request scope -->
<c:set var="notifyMsg" value="Operation succeeded" scope="request" />
<!-- Set property of existing employee object -->
<c:set target="${empInfo}" property="salary" value="20000" />

c:out Tag

Outputs content to the page, supports default values and HTML escaping:

<!-- Output notifyMsg, show default value if null, escape HTML tags by default -->
<c:out value="${notifyMsg}" default="No notification" escapeXml="true" />

Set escapeXml="false" to allow rendering of HTML/JS content in the output value.

c:if Tag

Implements single conditional judgment:

<c:if test="${not empty empInfo}">
  <p>Employee information loaded successfully</p>
</c:if>

c:choose + c:when + c:otherwise Tags

Implements multi-conditional branching:

<c:set var="examScore" value="87" />
<c:choose>
  <c:when test="${examScore >= 90 and examScore <= 100}">A</c:when>
  <c:when test="${examScore >= 80 and examScore < 90}">B</c:when>
  <c:when test="${examScore >= 60 and examScore < 80}">C</c:when>
  <c:otherwise>D</c:otherwise>
</c:choose>

c:forEach Tag

Iterates over collections, arrays, or numeric ranges:

<%@ page import="java.util.*,com.example.entity.Employee" pageEncoding="UTF-8" %>
<%
  List<Employee> empList = new ArrayList<>();
  empList.add(new Employee(1001, "li_ming", 22000));
  empList.add(new Employee(1002, "wang_hua", 18000));
  empList.add(new Employee(1003, "zhao_si", 15000));
  pageContext.setAttribute("empList", empList);
%>
<table border="1">
  <tr>
    <th>Serial No.</th>
    <th>Employee ID</th>
    <th>Name</th>
    <th>Salary</th>
  </tr>
  <c:forEach items="${empList}" var="emp" varStatus="stat">
    <tr>
      <td>${stat.count}</td>
      <td>${emp.empId}</td>
      <td>${emp.empName}</td>
      <td>${emp.salary}</td>
    </tr>
  </c:forEach>
</table>

The varStatus attribute provides iteration state: count (1-based serial number), index (0-based index), first (indicates if current element is the first), last (indicates if current element is the last).

c:url + c:param Tags

Generates encoded URLs with automatic context path addition and parameter encoding:

<c:url var="downloadLink" value="/file/DownloadServlet">
  <c:param name="fileName" value="2024 Annual Report.pdf" />
</c:url>
<a href="${downloadLink}">Download Annual Report</a>

c:redirect Tag

Implements client-side redirect:

<c:redirect url="/login.jsp" />

JSTL Function Tag Library (prefix fn)

Provides common string manipulation functions:

Function Usage Description
toLowerCase ${fn:toLowerCase("HELLO")} Converts string to lowercase
toUpperCase ${fn:toUpperCase("hello")} Converts string to uppercase
trim ${fn:trim(" test ")} Removes leading and trailing whitespace
split ${fn:split("a,b,c", ",")} Splits string into array by delimiter
join ${fn:join(stringArray, "-")} Joins array elements into string with delimiter
contains ${fn:contains("test string", "str")} Checks if string contains substring
startsWith ${fn:startsWith("test", "te")} Checks if string starts with prefix
endsWith ${fn:endsWith("test.pdf", ".pdf")} Checks if string ends with suffix
replace ${fn:replace("test", "t", "b")} Replaces all matching substrings
substring ${fn:substring("test", 0, 2)} Extracts substring from start index to end index

Example usage:

<c:set var="originalStr" value="Hello JSP EL JSTL" />
Uppercase: ${fn:toUpperCase(originalStr)}<br/>
Length: ${fn:length(originalStr)}<br/>
Contains "EL": ${fn:contains(originalStr, "EL")}

Tags: JSP EL Expression JSTL Java Web servlet

Posted on Mon, 12 Oct 2026 16:26:42 +0000 by Katmando