JSP directives give the container page-level instructions before a JSP is translated into a servlet. The three core directives are page, include, and taglib.
Use the page directive for settings such as imports, content type, encoding, and error pages. Use include for static file inclusion at translation time, and taglib to make JSTL or custom tags available.
The important distinction is timing: the include directive combines source files before translation, while <jsp:include> runs during each request.
Directive syntax starts with <%@ and ends with %>. A directive configures the generated servlet; it does not directly write output to the response.
The JSP container reads directives while translating the page into servlet source. That means directive settings affect compilation, dependencies, imports, and page behavior before a request reaches the generated servlet. In a typical MVC application, the controller prepares data, forwards to a JSP under WEB-INF, and the JSP uses directives only for view configuration. Keeping that boundary clear prevents business logic from drifting into templates and makes the rendered page easier to test.
| Directive | Purpose | Typical use |
|---|---|---|
| page | Configures the JSP page | Imports, encoding, sessions, error handling |
| include | Merges another file at translation time | Shared static header or footer fragments |
| taglib | Declares a tag library and prefix | JSTL core, formatting, or custom tags |
A page can contain multiple page directives, but duplicate attributes must not conflict. Keep UTF-8 settings explicit and place reusable view logic in tags rather than scriptlets.
<%@ page contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
import="java.time.LocalDate" %>
<%@ include file="/WEB-INF/fragments/header.jspf" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<p>Today: <%= LocalDate.now() %></p>
<c:if test="${not empty sessionScope.user}">
<p>Welcome, <c:out value="${sessionScope.user.name}" /></p>
</c:if>
The include directive is static: the referenced source becomes part of the JSP when the container translates it. Changes may trigger recompilation.
<jsp:include> is dynamic: the target resource runs for the current request and its response is inserted into the page.
When a directive-related page fails, read the first JSP translation or compilation error rather than the later servlet stack trace. The first message usually identifies the invalid attribute, unresolved tag prefix, duplicate declaration, missing fragment, or encoding problem that caused the generated servlet to fail.
On the first request, or after a JSP source change, the container reads the main JSP and any translation-time include fragments. It applies page settings, resolves tag libraries, translates the combined template into Java servlet source, compiles that source, and loads the resulting servlet class. Later requests normally execute the compiled servlet until the container detects another source change.
This lifecycle explains why a bad directive can fail before any visible HTML is rendered. A missing include file stops translation. An invalid import or conflicting declaration can break Java compilation. A missing tag library prevents the container from resolving a prefix. In development, inspect the server log and generated-source line mapping; in production, avoid exposing container paths or stack traces to users.
Directive choice also affects maintainability. Static includes are convenient for small stable fragments, but a large tree of includes can create duplicate declarations and unclear dependencies. JSTL, tag files, template libraries, or a component-oriented view layer usually scale better when fragments need parameters, conditional behavior, escaping, or independent testing.
<%@ page errorPage="/WEB-INF/views/error.jsp"
contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ page isErrorPage="true"
contentType="text/html; charset=UTF-8" %>
<p>Request failed: ${pageContext.exception.message}</p>
The directive combines source during JSP translation. jsp:include runs the target for each request and includes its response.
Set pageEncoding and contentType in the page directive, and configure request encoding before reading submitted parameters.
The URI must match an installed tag library, and the required JSTL dependency must be available to the application.
Explore 500+ free tutorials across 20+ languages and frameworks.