LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 820 min read

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.

A scriptlet with a for loop
<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>
Rendered 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.

Expressions inserting values
<p>2 + 2 = <%= 2 + 2 %></p>
<p>Current year: <%= java.time.Year.now() %></p>
<p>Username parameter: <%= request.getParameter("user") %></p>
Rendered HTML for a request like ?user=Asha

Click Run to see what this code prints.

Expressions Are Just Sugar

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.

A declaration with a shared counter field and a helper method
<%!
private int visitCount = 0;
private String formatCount(int count) {
return "Visits so far: " + count;
}
%>
<%
visitCount++;
%>
<p><%= formatCount(visitCount) %></p>
Declarations Are Shared, Not Per-Request

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.

scripting-demo.jsp
<%! // 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>
ElementSyntaxBecomes 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.
Legacy vs Modern

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

Avoid These 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.

Next Lesson →

JSP Directives