By WebNest Studio Engineering Team
Advanced Java Tutorial
JSP Directives and Actions
Beyond scripting elements, JSP has two other tag families that control how a page is processed: directives, which configure page-level settings understood at translation time, and actions, which perform tasks at request time using XML-style tags. Both look similar to scripting tags but serve very different purposes, and confusing the two is a common source of mistakes for beginners.
Directives: page, include, taglib
A directive gives the container instructions about the page as a whole, processed during translation rather than at request time. Directives use the syntax <%@ directiveName attribute="value" %>.
page— configures page-wide settings such ascontentType,import(for Java classes used in scriptlets/expressions),session(enable/disable),errorPage, andisErrorPage.include— performs a static, translation-time include of another file's raw content, merging it into this page's source before compilation (different from the include action below, which happens at request time).taglib— declares a tag library prefix, such as<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>, which is required before using JSTL tags like<c:forEach>.
Standard Actions
Actions use XML tag syntax (<jsp:actionName />) and execute at request time, unlike directives. The most commonly used standard actions mirror the servlet mechanisms you already know: <jsp:forward page="target.jsp" /> transfers control to another resource (like RequestDispatcher.forward), <jsp:include page="fragment.jsp" /> includes another resource's output at request time (like RequestDispatcher.include, and distinct from the include directive), and <jsp:useBean>/<jsp:setProperty>/<jsp:getProperty> work with JavaBean objects in a given scope.
Include Directive vs Include Action
This distinction trips up many learners: the include directive (<%@ include file="header.jsp" %>) merges the included file's source at translation time, before compilation — so it behaves as if you had pasted the content in by hand, and any change to the included file requires the including page to be recompiled to take effect. The include action (<jsp:include page="header.jsp" />) instead calls the target resource at request time and inserts its live output, meaning the included page can be changed independently and always reflects its latest compiled version.
Examples
Page and taglib directives combined with JSTL, plus jsp:include
<%@ page contentType="text/html;charset=UTF-8" import="java.util.List" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html><body>
<jsp:include page="/WEB-INF/views/header.jsp" />
<h2>Product List</h2>
<ul>
<c:forEach var="item" items="${productList}">
<li>${item}</li>
</c:forEach>
</ul>
<jsp:include page="/WEB-INF/views/footer.jsp" />
</body></html>
Browser output (assuming productList = ["Mouse", "Keyboard"]):
[header content]
Product List
- Mouse
- Keyboard
[footer content]
jsp:forward vs jsp:include — control transfer vs embedding
<%-- forward: control leaves this page entirely, URL logic handled server-side --%>
<jsp:forward page="/WEB-INF/views/thankyou.jsp" />
<%-- include: output of cart-summary.jsp is embedded here, and this page continues after it --%>
<jsp:include page="/WEB-INF/views/cart-summary.jsp" />
<p>Continue shopping below.</p>
With jsp:forward, only thankyou.jsp's output reaches the browser. With jsp:include, cart-summary.jsp's output appears, followed by "Continue shopping below."
Common Mistakes
- Confusing the include directive (<%@ include %>, translation-time, static) with the include action (<jsp:include />, request-time, dynamic).
- Forgetting the taglib directive before using JSTL tags, which causes the tags to be treated as literal, unrecognized text.
- Using <jsp:forward> after content has already been flushed to the response, which fails because the response is already committed.
- Placing directive attributes with incorrect syntax (missing quotes, wrong attribute names) and getting confusing translation-time errors.
Exercise
A teammate is about to make this mistake: Confusing the include directive (<%@ include %>, translation-time, static) with the include action (<jsp:include />, request-time, dynamic). Use Directives: page, include, taglib to review the decision. Write a corrected implementation or design sketch that follows Directives (page, include, taglib) configure the page at translation time; actions (jsp:forward, jsp:include, jsp:useBean) execute at request time., then name one edge case you would check.
Show hints
- Start with Directives: page, include, taglib and compare your approach with Page and taglib directives combined with JSTL, plus jsp:include. Identify the decision or behavior the lesson recommends.
- Walk through your scenario step by step. Confirm that it follows Directives (page, include, taglib) configure the page at translation time; actions (jsp:forward, jsp:include, jsp:useBean) execute at request time. and that it would catch the failure described by Confusing the include directive (<%@ include %>, translation-time, static) with the include action (<jsp:include />, request-time, dynamic)..
Quick quiz
1. Which choice best describes the recommended approach in JSP Directives and Actions?
- A. Confusing the include directive (<%@ include %>, translation-time, static) with the include action (<jsp:include />, request-time, dynamic).
- B. Forgetting the taglib directive before using JSTL tags, which causes the tags to be treated as literal, unrecognized text.
- C. Directives (page, include, taglib) configure the page at translation time; actions (jsp:forward, jsp:include, jsp:useBean) execute at request time.
Show answer
C. This is the recommended approach: Directives (page, include, taglib) configure the page at translation time; actions (jsp:forward, jsp:include, jsp:useBean) execute at request time. Avoid: Confusing the include directive (<%@ include %>, translation-time, static) with the include action (<jsp:include />, request-time, dynamic).
Interview questions
Why does this principle matter in JSP Directives and Actions: Directives (page, include, taglib) configure the page at translation time; actions (jsp:forward, jsp:include, jsp:useBean) execute at request time.
Show answer
Directives (page, include, taglib) configure the page at translation time; actions (jsp:forward, jsp:include, jsp:useBean) execute at request time. Apply this in Directives: page, include, taglib; the example Page and taglib directives combined with JSTL, plus jsp:include shows one way to do it. Avoid Confusing the include directive (<%@ include %>, translation-time, static) with the include action (<jsp:include />, request-time, dynamic). and explain how your implementation or design prevents that failure.
Key Points to Remember
- Directives (page, include, taglib) configure the page at translation time; actions (jsp:forward, jsp:include, jsp:useBean) execute at request time.
- The include directive pastes source at compile time; the include action calls the target and embeds live output at request time.
- taglib must be declared before using any JSTL or custom tag library on a page.
- jsp:forward transfers control completely; jsp:include embeds another resource's output and returns control to the caller.
Practice in the playground
Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.
Run the examples
Change an input, predict the result, then compare it with the output. Explain why the result changes.
These examples need a JDK project with their libraries on your computer, so they can be copied but not run here. Codelab runs Python, FastAPI backends with SQLite, plain Java 17 and HTML/CSS/JavaScript.
Written by
WebNest Studio Engineering Team
Practical lessons from developers working with Java, Python, React, databases and production systems.
Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering