JSP Scripting Elements
JSP Scripting Elements
JavaServer Pages were designed as a way to embed dynamic output directly inside HTML. To do that, the original specification defined three scripting elements that let you write Java inside a .jsp file: scriptlets, expressions, and declarations. Every JSP developer needs to recognise these constructs — both to maintain legacy code and to understand exactly why modern JSP deliberately avoids them.
How JSP Compilation Works
Before diving into the syntax it helps to understand what the servlet container actually does with a JSP file. When a request arrives for a .jsp resource, the container (Tomcat, WildFly, etc.) translates it into a plain Java source file that extends HttpJspBase, compiles that file to bytecode, and then serves subsequent requests from the compiled servlet — exactly like a hand-written HttpServlet. The scripting elements are literal Java code that is spliced into the generated class. This translation model is why scripting elements are both powerful and dangerous.
Scriptlets: <% ... %>
A scriptlet places arbitrary Java statements inside the generated _jspService() method. The syntax is <% javaCode; %>.
The container weaves the HTML fragments between the scriptlet blocks into out.write("...") calls. The result compiles and runs, but the generated source is a mess of interleaved Java and string-writing calls that is nearly impossible to test or maintain.
Expressions: <%= ... %>
An expression element evaluates a single Java expression and writes its toString() value directly into the response. There is no semicolon inside an expression tag.
The container translates <%= expr %> into out.print(expr);. Note that if the expression evaluates to null, the string "null" is written to the output — there is no null safety.
out.print() scriptlet. You cannot use statements (assignments, loops, conditionals) inside an expression tag — only a single value-producing expression.
Declarations: <%! ... %>
A declaration places code at the class level of the generated servlet, outside _jspService(). You can declare instance variables and methods here.
The Page Directive
Almost every JSP file starts with a page directive, which configures settings for the generated servlet. It is not a scripting element, but it always appears alongside them.
Key attributes: import adds import statements to the generated class; contentType sets the response Content-Type header; errorPage redirects uncaught exceptions to a dedicated error page.
Why Modern JSP Avoids Scriptlets
The Java EE community reached a broad consensus — enshrined in Sun's Core J2EE Patterns and later the JSP 2.0 specification guidance — that scriptlets should not appear in production JSP files. The reasons are concrete:
- Untestable code. Logic inside a scriptlet can only be exercised by deploying the page and making an HTTP request. There is no way to write a unit test for a scriptlet block.
- Designer-hostile syntax. HTML/CSS designers and front-end engineers cannot work with JSP files littered with Java. Tools like IDEs and static analysers struggle with the mixed syntax.
- Maintenance cost. Interleaved Java and HTML multiplies the cognitive load of every change. Studies of legacy codebases consistently show JSP scriptlets as a maintenance hotspot.
- Better alternatives exist. The Expression Language (EL) and JSTL — covered in the next lessons — provide declarative, designer-friendly replacements for every common scriptlet pattern (iteration, conditionals, formatting). Thymeleaf and FreeMarker go further by being valid HTML even before template processing.
<scripting-invalid>true</scripting-invalid> to the <jsp-property-group> in your web.xml. Doing so turns any remaining scriptlet in the project into a compile-time error — a useful guard rail when onboarding a legacy codebase.
Quick Reference: The Three Scripting Elements
<% statements; %>— Scriptlet: arbitrary Java statements, placed in_jspService(). Avoid in new code.<%= expression %>— Expression: a single Java expression whose value is printed to the response. Superseded by EL${expression}.<%! declaration %>— Declaration: class-level members (fields, methods). Risky due to shared mutable state; rarely needed.
Summary
Scriptlets, expressions, and declarations let you embed Java directly inside HTML — which is exactly what makes them problematic. They tangle view concerns with logic, produce untestable code, and require understanding the translation model (generated servlet class, _jspService() method) to reason about their behaviour. Modern JSP development replaces all three with EL and JSTL, which deliver the same dynamic output without mixing languages. In the next lesson you will explore the implicit objects that are always available in every JSP — understanding them rounds out the picture before we move to EL and JSTL.