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:
language: Fixed valuejavafor standard JSP implementations, specifies the scripting language for scriptlets.import: Declares Java class dependencies, multiple packages are separated by commas.session: Defaults totrue, automatically creates anHttpSessionobject for the current request if no existing session is found.buffer: Sets the size of theJspWriteroutput buffer, default value is 8kb. Output content is flushed to the browser only when the buffer is full or page rendering completes.errorPage: Defines the redirect target when an uncaught exception occurs on the current page for page-level exception handling.isErrorPage: Set totrueon exception handling pages to expose the built-inexceptionobject for error detail retrieval.isELIgnored: Defaults tofalse, 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:
- Wraps all other implicit objects, can retrieve any other built-in object via corresponding getter methods.
- Supports data storage and retrieval across all 4 scope levels (page, request, session, application).
- 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
outis first stored in the JSP output buffer, then flushed to thePrintWriterbuffer before being sent to the browser. - Content written directly to
PrintWriterbypasses 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
- Scope-related:
pageScope,requestScope,sessionScope,applicationScope(retrieve attributes from specified scopes) - Request parameter:
param(single parameter),paramValues(array of parameters for multi-value fields) - Request header:
header(single header),headerValues(array of header values) cookie: Retrieve cookie name and value pairsinitParam: Retrieve context initialization parameters configured inweb.xmlpageContext: 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
- Arithmetic operators:
+,-,*,/(ordiv),%(ormod) - Comparison operators:
==(oreq),!=(orne),<(orlt),>(orgt),<=(orle),>=(orge) - Logical operators:
&&(orand),||(oror),!(ornot) - Empty check operator:
empty(returns true for null, empty string, empty collection, empty array) - 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")}