JSP Scripting Elements
Learn scriptlets, expressions, and declarations - the three classic ways to embed Java in JSP - and why modern JSP favors EL and JSTL instead.
Introduction
JSP's original design gave developers three distinct ways to embed Java code directly into a page: scriptlets, expressions, and declarations. These are collectively called scripting elements, and they were the primary way to write logic in early JSP pages. You will still encounter them constantly in legacy code, so understanding them well is essential - even though, as you will see at the end of this lesson, modern JSP style has largely moved away from them.
Scriptlets: <% %>
A scriptlet lets you write any block of ordinary Java code - statements, loops, conditionals - directly inside a JSP page. The syntax is <% ... %>. Code inside a scriptlet becomes part of the generated _jspService() method, so it runs fresh on every request.
<html><body> <h2>Multiplication Table of 5</h2> <ul> <% for (int i = 1; i <= 5; i++) { %> <li>5 x <%= i %> = <%= 5 * i %></li> <% } %> </ul></body></html>Click Run to see what this code prints.
Notice how the scriptlet's opening brace and closing brace are split across two separate <% %> blocks, with plain HTML in between. This is a valid and common (if visually odd) pattern - the container simply concatenates all the Java fragments in order when it generates _jspService().
Expressions: <%= %>
An expression evaluates a single Java expression and inserts the resulting value directly into the output, as text. The syntax is <%= ... %>. Crucially, there is no semicolon at the end - it is a single expression, not a statement.
<p>2 + 2 = <%= 2 + 2 %></p><p>Current year: <%= java.time.Year.now() %></p><p>Username parameter: <%= request.getParameter("user") %></p>Click Run to see what this code prints.
An expression <%= value %> is roughly equivalent to writing <% out.print(value); %> as a scriptlet - it is a shorter, cleaner syntax for the extremely common case of printing a single value.
Declarations: <%! %>
A declaration defines a method or a field (instance variable) on the generated servlet class itself, rather than inside _jspService(). The syntax is <%! ... %>. This is exactly how jspInit() and jspDestroy() were overridden in the previous lesson.
<%! private int visitCount = 0;
private String formatCount(int count) { return "Visits so far: " + count; }%><% visitCount++;%><p><%= formatCount(visitCount) %></p>Because a declaration becomes a field on the servlet instance (not a local variable inside _jspService()), its value is shared across every request handled by that servlet instance - and multiple threads may access it concurrently. This makes declarations risky for anything mutable, like the visitCount above, in a real multi-user application.
Combining All Three
Here is a single page using all three scripting elements together, to see how they relate to the lifecycle from the previous lesson.
<%! // Declaration - becomes a servlet field/method private String greetName(String name) { return (name == null || name.isEmpty()) ? "Guest" : name; }%><% // Scriptlet - runs inside _jspService() on every request String rawName = request.getParameter("name"); String finalName = greetName(rawName);%><html><body> <!-- Expression - prints a value inline --> <h1>Welcome, <%= finalName %>!</h1></body></html>| Element | Syntax | Becomes in Generated Servlet |
|---|---|---|
| Declaration | <%! %> | A field or method on the servlet class |
| Scriptlet | <% %> | A statement inside _jspService() |
| Expression | <%= %> | An argument to out.print(...) inside _jspService() |
Why Modern JSP Avoids Scriptlets
Scripting elements were the only option in early JSP, but the Java web community learned over time that mixing large amounts of raw Java logic directly into HTML markup causes the same readability and maintainability problems JSP was originally meant to solve for Servlets.
- Scriptlet-heavy JSP pages are hard for designers (non-Java developers) to safely edit.
- Java logic scattered through HTML is difficult to unit test.
- Mixing string parameter names and control flow directly in markup is error-prone and hard to review.
- Expression Language (EL) and JSTL, covered in the next two lessons, were introduced specifically to replace this pattern with cleaner, tag-based syntax.
You will still see scriptlets constantly in older enterprise JSP codebases, which is exactly why this lesson covers them in depth. But when writing new JSP code today, the accepted best practice is Expression Language plus JSTL, which you will learn in the final two lessons of this course.
Common Mistakes
- Adding a semicolon inside an expression, like <%= 2 + 2; %>, which causes a compilation error.
- Declaring mutable instance fields (like counters) inside a <%! %> declaration without considering multi-threading.
- Writing large amounts of business logic in scriptlets instead of moving it to a Servlet or a helper class.
- Forgetting that declarations live outside _jspService() and are shared across all requests to that page.
Best Practices
- Prefer Expression Language (${ }) over scriptlet expressions (<%= %>) whenever possible - covered in a later lesson.
- Keep scriptlets short, and move any nontrivial logic to a Servlet or a plain Java helper class instead.
- Avoid mutable state in declarations unless you fully understand servlet threading behavior.
- When maintaining legacy scriptlet-heavy pages, resist rewriting everything at once - understand the flow first.
Frequently Asked Questions
A scriptlet <% %> can contain any Java statements (loops, conditionals, assignments) and produces no output by itself. An expression <%= %> evaluates a single value and inserts it directly into the page output.
A declaration becomes a member (field or method) of the generated servlet class, so it persists across requests and is shared by all threads handling that page. A scriptlet becomes local code inside _jspService(), which is fresh on every request.
They are not formally deprecated in the specification, but they are strongly discouraged in modern JSP development in favor of Expression Language and JSTL, which you will learn next.
Yes, technically you can mix them, though it is best practice to pick one consistent style. Most modern pages use EL/JSTL and avoid scriptlets almost entirely.
Key Takeaways
- Scriptlets <% %> embed arbitrary Java statements that run inside _jspService() on every request.
- Expressions <%= %> evaluate a single value and print it directly into the output, with no semicolon.
- Declarations <%! %> define fields or methods on the generated servlet class, shared across requests.
- Declarations require care with mutable state due to being shared across concurrent requests.
- Modern JSP avoids scriptlets in favor of Expression Language and JSTL for readability and maintainability.
Summary
Scriptlets, expressions, and declarations were JSP's original tools for embedding Java logic, and understanding them is essential for reading legacy code. But as you saw, mixing heavy Java logic into markup reintroduces the same readability problems JSP was designed to solve. Next, you will learn about JSP directives - page-level instructions that configure how a JSP file is processed, imported, and included.