Question
In JSP, code such as the following was traditionally used to embed Java directly in a page:
<%= x + 1 %>
<%= request.getParameter("name") %>
<%! counter++; %>
This older style mixes Java code with presentation markup. In JSP 2, how can these lines be replaced using the modern approach that avoids putting Java code directly in JSP files? What is this technique called?
Short Answer
By the end of this page, you will understand how JSP 2 avoids Java scriptlets by using Expression Language (EL) and tag libraries such as JSTL. You will see how values are displayed, how request data is accessed, why direct Java declarations should be avoided in JSPs, and how real JSP applications separate presentation from business logic.
Concept
JSP originally allowed developers to write Java code directly inside HTML using scriptlets, expressions, and declarations.
Examples:
<%= x + 1 %>
<%= request.getParameter("name") %>
<%! int counter = 0; %>
This style became hard to maintain because:
- HTML and Java logic were mixed together
- pages became difficult to read
- testing was harder
- business logic often leaked into the view layer
In JSP 2, the preferred approach is to use:
- Expression Language (EL) for reading and displaying values
- JSTL (JSP Standard Tag Library) for common view logic such as conditions, loops, and variable assignment
- Servlets, controllers, or backing code for actual Java logic and state changes
This approach is often called:
- using EL instead of scriptlets
- scriptlet-free JSP
- Model 2 / MVC-style JSP development
Why this matters:
- JSP should mainly handle presentation
- Java code belongs in servlets, controllers, or Java classes
- pages become cleaner and easier to maintain
- teams can separate backend and frontend responsibilities more clearly
For the three original lines:
<%= x + 1 %>
<%= request.getParameter("name") %>
<%! counter++; %>
Modern JSP 2 alternatives are typically:
${x + 1}
${param.name}
The third line has no direct equivalent that should be written in the JSP. Updating application state such as counter++ should be done in Java code outside the JSP, then the result can be displayed in the page using EL.
For example:
${counter}
if counter was already updated by a servlet or controller before forwarding to the JSP.
Mental Model
Think of a JSP page as a template for displaying data, not a place for doing real work.
- Servlet/controller = the chef who prepares the meal
- JSP = the waiter who serves it neatly
- EL/JSTL = the polite language the waiter uses to present what was prepared
- Scriptlets = asking the waiter to go cook in the kitchen during service
That is why JSP 2 encourages you to prepare data first in Java, then let the JSP simply display it.
Syntax and Examples
Core syntax
Old scriptlet-style JSP
<%= x + 1 %>
<%= request.getParameter("name") %>
<% counter++; %>
Modern JSP 2 style with EL
${x + 1}
${param.name}
Using JSTL to store a display value
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="nextValue" value="${x + 1}" />
<p>${nextValue}</p>
<p>${param.name}</p>
Example
Assume a servlet sets an attribute:
request.setAttribute("x", 5);
request.getRequestDispatcher("/WEB-INF/view/example.jsp").forward(request, response);
Then in the JSP:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<p>Next number: ${x + 1}</p>
<p>Name: ${param.name}</p>
Explanation
${x + 1}reads the attributexand adds 1${param.name}reads the HTTP request parameter namedname- No Java code is embedded directly in the JSP
What about counter++?
Do not increment values inside the JSP as page logic. Instead, do it before rendering:
Integer counter = (Integer) application.getAttribute("counter");
if (counter == null) {
counter = 0;
}
counter++;
application.setAttribute("counter", counter);
request.setAttribute("counter", counter);
Then display it:
<p>Counter: ${counter}</p>
Step by Step Execution
Consider this servlet and JSP pair.
Servlet
request.setAttribute("x", 7);
request.getRequestDispatcher("/result.jsp").forward(request, response);
JSP
<p>${x + 1}</p>
<p>${param.name}</p>
Step-by-step
- The servlet receives the request.
- It stores
7in the request attribute namedx. - The request is forwarded to
result.jsp. - In the JSP,
${x + 1}looks up the attributex. - EL finds
x = 7. - EL evaluates
7 + 1and prints8. ${param.name}looks in the request parameters.- If the URL was something like
?name=Alice, EL printsAlice.
Trace example
Request URL:
/result?name=Alice
Output:
<p>8</p>
<p>Alice</p>
Notice that the JSP only reads prepared data and request input. It does not contain Java statements.
Real World Use Cases
JSP 2 scriptlet-free style is useful in many real applications.
Displaying form input
<p>Welcome, ${param.username}</p>
Used after a login form or search form submission.
Showing data prepared by a controller
request.setAttribute("products", products);
Then in JSP:
${products}
More commonly, JSTL is used to loop through items.
Rendering validation messages
A servlet validates input and stores errors in request attributes. The JSP displays them without Java code.
Showing session or application state
${sessionScope.user}
${applicationScope.counter}
Useful for dashboards, login state, or app-wide values.
Building maintainable MVC web apps
Controllers handle logic, services handle business rules, and JSP focuses on rendering HTML.
Real Codebase Usage
In real projects, developers usually follow these patterns.
1. Controller prepares data
A servlet or framework controller:
- reads request parameters
- validates input
- calls service classes
- stores results in request/session scope
- forwards to a JSP
2. JSP reads values with EL
${user.name}
${order.total}
${param.search}
3. JSTL handles simple view logic
Examples include:
- conditional rendering with
<c:if> - branching with
<c:choose> - loops with
<c:forEach> - setting simple variables with
<c:set>
4. Guarding against null or missing data
Controllers often guarantee needed attributes exist before forwarding.
Example:
if (user == null) {
response.sendRedirect("login");
return;
}
request.setAttribute("user", user);
Then the JSP can safely render:
${user.name}
5. No business logic in JSP
Avoid doing calculations, updates, database access, or object creation in JSP pages. Real codebases keep JSP as a view layer only.
Common Mistakes
1. Trying to replace all Java statements with EL
EL is for accessing values and simple expressions, not for arbitrary Java statements.
Broken idea:
${counter++}
Why it is wrong:
- EL is not meant for mutating application state this way
- updating values should happen in Java code before rendering
2. Confusing request parameters with attributes
Broken code:
${request.name}
Correct code for a query/form parameter:
${param.name}
Correct code for a request attribute set by Java:
${name}
3. Continuing to use scriptlets in new JSPs
Old style:
<%= user.getName() %>
Better:
${user.name}
4. Putting counter logic directly in JSP
Broken code:
<% counter++; %>
Better:
counter++;
request.setAttribute("counter", counter);
Then in JSP:
${counter}
5. Forgetting JSTL taglib declaration when using JSTL tags
If you use tags like <c:set> or <c:if>, include the taglib:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
6. Mixing presentation and business logic
If your JSP contains loops with complex calculations, object creation, or database calls, too much logic is in the view. Move that work into Java classes or controllers.
Comparisons
| Approach | Purpose | Example | Recommended in JSP 2? |
|---|---|---|---|
| Scriptlet | Embed Java statements in JSP | <% counter++; %> | No |
| Expression | Print Java expression result | <%= x + 1 %> | No |
| Declaration | Declare fields/methods in JSP | <%! int counter; %> | No |
| EL | Read and display values | ${x + 1} | Yes |
| JSTL | View logic with tags | <c:if>, <c:forEach> | Yes |
| Servlet/controller | Business logic and state changes | request.setAttribute(...) | Yes |
EL vs Scriptlets
| Feature | EL | Scriptlets |
|---|---|---|
| Readability | High | Low in mixed pages |
| Java code in JSP | Minimal | Direct Java in page |
| Best for displaying values | Yes | Older approach |
| Best for business logic | No | Also not ideal |
| Modern JSP practice | Yes | Avoid |
JSTL vs writing raw Java in JSP
- JSTL is better for simple page tasks like loops and conditions.
- Raw Java in JSP is harder to maintain and should be avoided.
Cheat Sheet
Replace old JSP code
Old:
<%= x + 1 %>
<%= request.getParameter("name") %>
<% counter++; %>
Modern:
${x + 1}
${param.name}
For state changes like counter++:
- do it in a servlet/controller
- pass the result to the JSP
- display with EL
Main tools
- EL: read values and simple expressions
- JSTL: loops, conditions, variable setting
- Servlet/controller: real Java logic
Useful EL objects
${param.name}→ request parameter${requestScope.value}→ request attribute${sessionScope.user}→ session attribute${applicationScope.counter}→ application attribute
Basic EL examples
${user.name}
${x + 1}
${empty items}
JSTL taglib
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Rule of thumb
If the JSP needs to change data, call complex Java logic, or manage application state, that code belongs outside the JSP.
FAQ
What is the modern alternative to scriptlets in JSP?
Use Expression Language (EL) and JSTL instead of embedding Java code directly in JSP pages.
What is ${param.name} in JSP?
It is JSP EL syntax for reading the HTTP request parameter named name.
Can EL replace all Java code in a JSP?
No. EL is for reading values and simple expressions. Business logic and state changes should be done in Java classes or controllers.
What replaces <%= x + 1 %> in JSP 2?
Use:
${x + 1}
What replaces request.getParameter("name") in JSP 2?
Use:
${param.name}
What replaces counter++ in JSP 2?
There should usually be no direct JSP replacement. Increment the counter in a servlet or controller, then display the result in the JSP.
What is this technique called?
It is commonly called using Expression Language (EL), often together with JSTL, to create scriptlet-free JSP pages.
Is JSTL part of JSP 2 best practices?
Yes. JSTL is widely used with JSP 2 to keep view logic simple and avoid raw Java code in JSP files.
Mini Project
Description
Build a small JSP page that greets a user by name and shows a visit counter prepared by server-side Java code. This demonstrates the correct JSP 2 style: Java logic in a servlet, display logic in the JSP using EL.
Goal
Create a servlet and JSP pair where the servlet prepares data and the JSP displays it without scriptlets.
Requirements
- Read a
nameparameter from the request. - Increment a counter in Java code, not in the JSP.
- Store the counter as a request attribute.
- Forward the request to a JSP.
- Display the name and counter using EL only.
Keep learning
Related questions
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.
Choosing a @NotNull Annotation in Java: Validation vs Static Analysis
Learn how Java @NotNull annotations differ, when to use each one, and how to choose between validation, IDE hints, and static analysis tools.