JSP, EL & JSTL

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

Part I of the section covers Jakarta Pages 4.0, Jakarta Expression Language 6.0 and Jakarta Standard Tag Library 3.0 (API 3.0.2, implementation 3.0.1) on Jakarta Servlet 6.1, running on Apache Tomcat 11.0.26 and Java 21; the versions were verified on 2026-10-08. It builds bookshelf-jsp, the servlet and JSP variant of the Bookshelf scenario described on the section landing page, and it needs only the servlet foundations of Servlet Fundamentals. Part II, Apache Struts, uses the same pages as the view layer of its actions.

Diagram of the two Bookshelf applications on Tomcat 11. The browser sends requests either to a front servlet in bookshelf-jsp or to the Struts filter in bookshelf-struts. Both call the same service and repository, which read and write the data store, and then forward to a JSP view under WEB-INF that renders the HTML response back to the browser.
Figure 1. Part I builds the left-hand variant of the Bookshelf: a front servlet forwards to JSP views that render with EL and JSTL

What Part I covers

JSP is the oldest part of the stack and the part that every Java web framework of its generation still uses as a view. Part I explains how a page becomes a servlet, every element of its syntax, the Expression Language that replaced scriptlets, the five tag libraries of JSTL, and how to write your own tags. It then builds applications from those parts: a Model 2 application with a front controller, forms with validation and sessions, Spring MVC with JSP views, Jasper configuration for development and production, security and testing. The status of each technology is stated on its page: scripting elements and the SQL and XML libraries of JSTL are legacy, jsp:plugin and isThreadSafe are removed, and the EL and JSTL libraries are the current way to write a view.

Version matrix

Each Jakarta EE release fixes one version of each specification, and the package namespace changed once, between Jakarta EE 8 and 9. The table lists the releases a JSP application can still meet and the container line that implements each of them; the Jakarta EE 12 row is in progress and is not released.

Table 1. Pages, Expression Language, Tags and Servlet by Jakarta EE release
Jakarta EE Pages Expression Language Tags (JSTL) Servlet Tomcat line

9 and 9.1

3.0

4.0

2.0

5.0

10.0

10

3.1

5.0

3.0

6.0

10.1

11 (current)

4.0

6.0

3.0

6.1

11.0

12 (in progress)

4.1

6.1

3.1

6.2

none yet (Tomcat 12 is not released)

Everything from Jakarta EE 9 on uses jakarta.* packages, and Tags 3.0 renames the tag library URIs to jakarta.tags.* (jakarta.tags.core, jakarta.tags.fmt, jakarta.tags.functions, jakarta.tags.sql, jakarta.tags.xml). Java EE 8 and earlier (Pages 2.3, EL 3.0, JSTL 1.2, Servlet 4.0) used javax.* and the http://java.sun.com/jsp/jstl/... URIs. What’s Changed & Migration lists every change between them.

Container support matrix

Any Jakarta EE 11 servlet container runs the examples. The three that matter in practice differ in what they are and how they provide the JSP engine; the full comparison and the installation steps are on Getting Started.

Table 2. Tomcat, Jetty and GlassFish for JSP (verified 2026-10-08)
Apache Tomcat 11.0.26 Eclipse Jetty 12.1.14 Eclipse GlassFish 8.0.5

Specifications

Servlet 6.1, Pages 4.0, EL 6.0, WebSocket 2.2 (the Jakarta EE 11 servlet-container set); Java 17 or later

One environment per Jakarta EE release (ee8 to ee11); ee11 is the Jakarta EE 11 environment, and the application must use jakarta.*

A full Jakarta EE 11 application server (Platform and Web Profile distributions)

JSP and EL engines

Jasper and its own EL implementation, built in

Apache Jasper, packaged with the ee11-jsp module and jetty-ee11-apache-jsp

Eclipse WaSP (Pages) and Eclipse Expressly (EL)

JSTL

Not bundled: the API and the implementation travel in WEB-INF/lib

The WAR’s own JSTL jars were used

Provided by the server; a WAR that carries its own copy also ran

Older lines

Tomcat 10.1 (Servlet 6.0, Pages 3.1) on Java 11 or later; Tomcat 9.0 stays on javax.* (Servlet 4.0, Pages 2.3) with support ending no earlier than 2027-03-31

Jetty 12.0 and the ee8, ee9 and ee10 environments of 12.1

GlassFish 7.x (Jakarta EE 10)

Maven coordinates

The container supplies the Servlet, Pages and EL APIs, so a WAR compiles against them with provided scope. Tomcat does not ship JSTL, so the API and the implementation are added with default scope and travel inside the WAR.

The dependencies of bookshelf-jsp
<dependencies>
    <dependency>
        <groupId>jakarta.servlet</groupId>
        <artifactId>jakarta.servlet-api</artifactId>
        <version>6.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>jakarta.servlet.jsp</groupId>
        <artifactId>jakarta.servlet.jsp-api</artifactId>
        <version>4.0.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>jakarta.el</groupId>
        <artifactId>jakarta.el-api</artifactId>
        <version>6.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>jakarta.servlet.jsp.jstl</groupId>
        <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
        <version>3.0.2</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.web</groupId>
        <artifactId>jakarta.servlet.jsp.jstl</artifactId>
        <version>3.0.1</version>
    </dependency>
</dependencies>

The specification page of Pages lists its API as jakarta.pages:jakarta.pages-api, which does not exist on Maven Central; the artifact that does is jakarta.servlet.jsp:jakarta.servlet.jsp-api, as above. The JSTL implementation is still 3.0.1 (2023-01-19).

Reading order

The pages build on each other; read them in this order the first time and use them as a reference afterwards.

  1. Core JSP: lifecycle and translation first, then syntax, directives, implicit objects and scopes, scripting elements (to read legacy code), standard actions, composition, errors, encoding, JSP documents and configuration.

  2. Expression Language: the basics, then operators, lambdas and streams, static access, records and Optional, and configuration.

  3. JSTL: core, iteration, URLs, i18n, formatting, functions and the legacy SQL and XML libraries.

  4. Custom tags: simple tags, classic tags, the TLD and EL functions, and tag files.

  5. Building applications: Model 2 with servlets, forms and sessions, Spring MVC, Jasper, security, and testing and debugging.

mindmap root((JSP EL and JSTL)) Core JSP Lifecycle and translation Syntax and directives Implicit objects and scopes Scripting elements Includes and error pages Encoding and configuration Expression Language Basics and operators Lambdas and streams Static access and records ELProcessor JSTL Core and iteration URLs and i18n Formatting and functions SQL and XML legacy Custom tags SimpleTag Classic handlers TLD Tag files Building applications Model 2 Forms and sessions Spring MVC Jasper Security and testing

What’s covered

Core JSP

Expression Language

JSTL

Custom tags

Building applications