Page structure
Identify template text, directives and actions.
CodeBhavyaTurn accepted controller models into readable server-side views.
JSP, now specified as Jakarta Pages, builds response content on the server. This lesson connects a controller’s accepted model to a readable view using directives, Expression Language and tag actions. You will distinguish server execution from browser execution and choose an explicit model scope.
Our example is a fictional study report. The controller supplies a learner and a bounded list of courses; the view displays a summary, completion labels or an empty result. The lab is a JavaScript model, not a JSP engine, compiler or servlet container.
Identify template text, directives and actions.
Read accepted model properties and explicit scopes.
Render lists and branches without business scriptlets.
Keep untrusted text literal in an HTML view.
A browser requests an application URL. A controller can prepare data and forward internally to a JSP view. The server evaluates that view and sends generated response content; the browser receives the result rather than executing JSP directives or Java code.
The generated HTML may load CSS and JavaScript, which the browser then handles normally. JSP and browser JavaScript therefore act at different stages. A JavaScript click handler cannot directly call a Java method embedded in a JSP without a separate server interaction.
Uploading a .jsp file to a static frontend does not make it dynamic. A matched Java toolchain, JSP-capable web runtime and application dependencies are required. This website lesson publishes teaching HTML and a local demonstration only.
Validate and prepare a model.
Generate response content on the server.
Send HTML and response metadata.
Render HTML; execute browser scripts.
A JSP processor translates a page into a servlet-style implementation and compiles it for execution. Translation can happen ahead of requests or when required by the runtime. It is not accurate to assume the source is translated anew for every visit.
The generated component has initialization and destruction hooks, while the processor generates request-service logic. Page authors should not define their own _jspService implementation in a JSP page. Keep application initialization and resource ownership in suitable managed components.
A directive or unknown tag can fail during translation, while data access or property evaluation can fail during a request. Those are different boundaries; a browser preview of an HTML fragment does not prove the JSP source compiles.
Directives, tags and expressions.
Generate and compile implementation.
Evaluate the page with current data.
Send the chosen representation.
The lab intentionally skips translation and compilation. Its fixed HTML renderer demonstrates output decisions and rejects an unacceptable model. It is not a general JSP or EL interpreter.
Template text contributes ordinary response markup. A page directive declares page-level settings. A taglib directive associates a prefix with a tag library. Expression Language reads model values, and actions can render conditional or repeated content.
The following small page assumes the controller has set a request attribute named lessonReport. It declares source and response encodings explicitly and uses c:out for the learner in HTML text. The tag library URI identifies a library; it is not a browser script download.
The Jakarta Tags implementation must be available to the application. A Servlet/JSP container does not by itself guarantee that every external tag library is installed.
<%@ page contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Study report</title></head>
<body>
<h1>Study report</h1>
<p>Learner: <c:out value="${requestScope.lessonReport.learner}" /></p>
</body>
</html>session="false" is suitable for this request-only view when it does not need a session. The scope-collision lab separately models a session-scoped attribute to teach name lookup; it does not imply this request-only page enables session access.
The page directive controls settings such as pageEncoding and contentType. Source encoding determines how the processor reads the JSP file; response encoding determines how the output bytes represent characters. A meta charset in HTML helps the browser but cannot repair source bytes decoded incorrectly on the server.
The taglib directive introduces a prefix such as c for Jakarta Tags core actions. The include directive combines another resource’s source at translation time. These directives configure processing rather than directly rendering a visible control.
Modern Jakarta examples and older Java EE/JSTL examples have compatibility differences. Match the page syntax, tag-library implementation, API namespace, Java version and container. Do not fix a missing library by mechanically renaming every package or URI.
<%@ page pageEncoding="UTF-8"
contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<%@ include file="fragments/banner.jspf" %>The include fragment is an illustrative dependency, not a file added to this frontend patch. In a real project it must exist and be compatible with the translation unit. Keep directive settings consistent across included source.
Older JSP code can contain a Java expression that writes its result, a scriptlet containing request-time Java statements, and a declaration that adds members to the generated class. Recognizing these forms helps you read legacy pages without treating them as the preferred place for application logic.
A declaration can create shared instance state. A mutable current learner field has the same concurrency danger explained in Level 23. SQL, authentication and business mutation should not be scattered through page scriptlets.
Prefer a controller and service that prepare an accepted model, with EL and tags for presentation. JSP syntax does not automatically validate incoming values or encode Java expression output safely for HTML.
<%-- Syntax recognition only; avoid business logic in the page. --%>
<%= 2 + 3 %> <%-- Java expression output --%>
<% int localCount = 3; %> <%-- Scriptlet statement --%>
<%! private int count; %> <%-- Shared member: concurrency concern --%>
<%-- Preferred presentation of an accepted model value: --%>
<c:out value="${requestScope.lessonReport.learner}" />The declaration is shown as a warning example, not an implementation recommendation. The lab never executes these scripting elements.
An EL expression such as ${requestScope.lessonReport.learner} reads a property from a scoped model. For a conventional JavaBean, a learner property can be exposed by a public getLearner method. Map keys can also be accessed through EL; the backing object’s type matters.
EL is not JavaScript. Do not assume browser object semantics, arbitrary Java statements or DOM operations work inside an EL expression. In template text, displaying a value through EL alone is not automatic HTML escaping.
Give the view a stable contract rather than making it guess between raw parameters, missing fields and database rows. The study report contract supplies a learner string and a list of courses with title and completed properties.
// Illustrative JavaBean getter within a report model class:
public String getLearner() {
return learner;
}
// Controller fragment after validation and service work:
request.setAttribute("lessonReport", acceptedReport);
// In the view:
// ${requestScope.lessonReport.learner}The getter and controller lines are fragments that need their surrounding Java classes and handler. The JavaScript lab uses plain objects to simulate an accepted model; it does not verify JavaBean resolution in a real JSP engine.
JSP scoped attributes can live in page, request, session or application scope. For an ordinary unqualified scoped attribute name, lookup searches page, request, session and application in that order. An explicit requestScope lookup states which scope the view expects.
If the controller forgets the request attribute, an unqualified lessonReport might resolve to a session attribute with the same name. A page-scoped attribute can also shadow the intended request model. This can produce plausible but wrong output instead of an obvious missing-model failure.
The lab contrasts one exact qualified lookup with one exact unqualified attribute lookup. It does not implement all EL identifiers, implicit objects, nested expressions or coercion rules. Its session model is fixed teaching data, not a real session.
First unqualified candidate.
Controller’s per-request model.
Longer-lived client-associated data.
Shared application attributes.
The default request-qualified mode ignores the page collision and session fallback. If its request model is missing, the lab returns a simulated 500 before rendering. A real JSP may display an empty value for a missing expression; this guard is an application contract in the model, not a guarantee supplied by EL.
JSP also provides implicit objects for scripting contexts, including request, response, out, pageContext, application and config. The session object depends on session support; exception is available for an error page configured appropriately. EL has its own implicit names such as requestScope, param and paramValues, so do not treat the two sets as identical.
param contains incoming request values and paramValues exposes repeated values. They are input, not the controller’s accepted report model. A submitted name or cookie is not proof of permission; validate input and authorize protected operations before choosing view data.
c:forEach repeats a body for items in a collection. Keep each row’s presentation simple: render the title and a controlled completion label. The collection should already meet the application’s model contract before the view receives it.
c:out escapes XML-sensitive characters by default and is appropriate here for plain HTML text. It is not a universal encoder for JavaScript strings, CSS or arbitrary URLs. Choosing the destination context remains part of correct output handling.
The following fragment reads explicitly from request scope. Its row variable is local to the iteration flow; it is not the same as a permanent learner field on a servlet.
<ul>
<c:forEach var="course" items="${requestScope.lessonReport.courses}">
<li>
<c:out value="${course.title}" />
<c:choose>
<c:when test="${course.completed}"> — Complete</c:when>
<c:otherwise> — Pending</c:otherwise>
</c:choose>
</li>
</c:forEach>
</ul>The lab’s normal rows are Java Servlets (complete), JSP <Views> (pending) and JDBC & SQL (pending). The source escapes the special characters while the safe preview shows the titles literally.
c:if conditionally includes its body. c:choose with c:when and c:otherwise selects a branch. These tags suit presentation decisions such as an empty list message or a completed/pending label; they should not replace backend authorization.
An empty collection can be accepted data. A view should complete with a clear message instead of showing a permanently loading box. A missing controller model and an accepted empty model are different outcomes.
The lab renders an accepted empty report with 200 and a zero-course summary. A malformed report returns 500 with no accepted model or course preview. The application decides these outcomes; JSP does not automatically impose them.
<c:choose>
<c:when test="${empty requestScope.lessonReport.courses}">
<p>No courses in this report.</p>
</c:when>
<c:otherwise>
<%-- Render the accepted list with c:forEach here. --%>
</c:otherwise>
</c:choose>Validate that the model exists separately. The empty operator is useful for presentation, but it should not silently make an absent model look like a legitimate zero-result report when the controller contract requires one.
The include directive inserts source during translation. The jsp:include action includes the output of another resource at request time. One combines source into a translation unit; the other dispatches for output while handling the current request.
Use a fragment for genuinely shared view markup and keep its assumptions documented. A source include can bring declarations and directives into the same unit, so it is not simply a runtime request to a separate page.
A dynamic include is still server-side processing. It does not mean the browser fetches an iframe or imports a JavaScript module. Do not use a fragment to bypass validation or access-control boundaries.
<%-- Translation-time source inclusion: --%>
<%@ include file="fragments/banner.jspf" %>
<%-- Request-time output inclusion: --%>
<jsp:include page="/WEB-INF/views/fragments/help.jsp" />These paths are illustrative dependencies for a real application. This static lesson patch adds neither a JSP server nor those fragment files. The global header/footer on this lesson remain the existing CodeBhavya frontend components.
A controller reads and validates request input, a service prepares application data, and the view renders an accepted report. This keeps persistence, permission and mutation logic out of the template and makes missing-model failures easier to locate.
An internal forward retains the same request and its attributes. Keeping the JSP under WEB-INF makes the controller the intended entry point because the view is not served as an ordinary direct resource. This arrangement does not replace authorization for protected operations.
A redirect creates a new client request; it does not automatically carry the previous request attributes. Use a deliberate read endpoint or other state mechanism rather than assuming an accepted model appears after any navigation.
// Illustrative controller fragment; acceptedReport is prepared first.
request.setAttribute("lessonReport", acceptedReport);
request.getRequestDispatcher("/WEB-INF/views/study-report.jsp")
.forward(request, response);
// Forward before committing response output.Validate and choose the outcome.
Prepare a bounded report model.
Render accepted presentation data.
Keep data access behind a boundary.
Treat learner labels and course titles as data. HTML text such as <Demo> must remain literal, even if it resembles a tag. Encoding in the response source and safe DOM rendering in the browser are separate checks.
The lab’s renderer escapes ampersands, angle brackets and quotes in text output. Its preview independently constructs fixed elements and sets textContent. It never inserts generated HTML with innerHTML or evaluates a submitted expression.
The fixed report has no dynamic link URLs, inline scripts or style values. If a real view introduces those contexts, it needs the appropriate validation and encoding rather than assuming c:out solves every destination.
<p>Learner: <c:out value="${requestScope.lessonReport.learner}" /></p>
<%-- JSP comments are not ordinary response HTML comments. --%>
<%-- Keep credentials and private diagnostics out of the source anyway. --%>
<!-- HTML comments can be present in the generated response. -->Do not turn untrusted input into JSP source or an EL expression to evaluate. Parameter validation controls the accepted data contract; output encoding controls how that accepted data appears in a specific destination.
A missing tag-library implementation, unknown action or invalid directive can stop translation. A property mismatch or failed service can stop request processing. Investigate the actual server logs and the first failing boundary rather than changing browser CSS for a server error.
If a learner disappears, compare the controller’s attribute name and scope with the expression in the page. If the wrong report appears, inspect page/session name collisions before assuming the repository returned another person’s data.
On an error, clear the previously accepted browser result. A failed run should not leave older course cards looking like its successful output. The lab displays a stable error and removes earlier rows.
Check Jakarta Tags dependency and URI compatibility.
Match bean getters or map keys to the view contract.
Use the controller’s intended request attribute.
Distinguish accepted empty output from missing/bad data.
The model validator rejects non-array course lists, sparse arrays, extra fields, non-boolean completion values and overlong or invalid strings. This is its explicit application guard, not a description of automatic JSP validation.
Validate and test the controller model independently, then compile and run the actual JSP in a matched container. Check tag-library resolution, EL property access, UTF-8 source/output, internal forwarding and the content returned over HTTP.
Use special-character labels and accepted empty lists alongside missing and malformed models. Compare the response source with the browser display. Confirm that a qualified request model does not accidentally pick up a session report with the same name.
The local lab tests its own scope lookup and renderer, including model copying and stale-output clearing. It cannot verify JSP translation, generated servlet behavior, JavaBean resolution, cookie/session handling or server concurrency.
Bounded data and deterministic summaries.
Compile directives, tags and expressions.
Check encoding, status and actual content.
Verify readability, keyboard use and literal text.
Level 25 continues with JDBC and Database Connectivity. Keep database operations in the backend data-access layer rather than adding SQL to the JSP view.
Follow an accepted report request through validation, model preparation, internal forwarding, JSP presentation and HTML output. This approved five-stage player explains the architecture without executing Java or JSP.
Validate the incoming learner before preparing data.
GET /report?learner=DemoThe controller handles input; the JSP view is not a substitute for validation.
This local JavaScript model accepts GET /report with exactly one learner query string. The learner must trim to 2–40 Unicode code points, with no C0/C1 controls or lone surrogates. No Java, JSP, EL engine, HTTP request or actual session runs here.
Compare requestScope.lessonReport with unqualified lessonReport. The modeled lookup searches page, request, session and application for the unqualified name. A page collision can shadow request data; a missing request model can fall back to a fixed session or application report. The default qualified lookup never falls back.
The accepted model requires exactly learner and courses; at most eight dense rows, each exactly title and completed. Learner uses the same bounded text rule; titles are trimmed 1–80 Unicode code points with no controls/lone surrogates; completed is boolean. A derived summary counts completed and pending rows. Model failure returns simulated 500 before rendering.
The template panel is explanatory JSP source. The generated HTML is a fixed JavaScript renderer, not evaluation of that template. The safe preview separately builds text nodes. The scope fixtures are public teaching values, not private user sessions.
Idle. JavaScript model; no JSP engine is running.
No trace yet.No scope lookup yet.No accepted model.No response yet.No response body yet.Confirm the controller sets lessonReport in request scope.
Check learner, course list and boolean completion values.
Verify the actual library and compatible URI.
Compare encoded source with literal visible text.
If qualified lookup reports a missing model, inspect the controller and dispatch rather than choosing unqualified lookup simply to suppress the error. A session fallback can display a different learner’s teaching fixture and hide the missing request attribute.
If a page collision is malformed, the unqualified lookup selects that value and the application model guard fails. It does not continue searching for a later valid object. If an empty report is accepted, render the explicit zero-course message.
A successful local preview proves neither JSP compilation nor JavaBean getters. Run the actual view in its matched environment and verify what the server sends.
No. A JSP-capable server processes the page and sends generated response content.
No. Translation/compilation may be performed ahead of time or when needed; request processing uses the resulting implementation.
Conventionally through a public getLearner method; map-backed models resolve keys instead.
It identifies the intended per-request model and avoids page/session/application name fallback.
The page value is selected first. A later scope is not chosen merely because the selected value is malformed.
The include directive combines source at translation time; jsp:include includes another resource’s output at request time.
No. Its default XML escaping suits this plain HTML text example; scripts, CSS and URLs need context-specific handling.
No. Actual translation, tag libraries, EL properties, forwarding and HTTP output require runtime integration tests.
Default run: request model, three courses, one complete and two pending. Expect 200.
Choose accepted empty. Expect 200, zero counts and a clear no-course message.
Choose missing with qualified lookup. Expect 500 and no old course preview.
Missing + unqualified + no page collision: session fixture wins. Remove session fixture: application wins.
Normal request + valid page collision + unqualified: page report wins. Qualified lookup still uses request.
Invalid page collision + unqualified: 500. A later valid request model is not substituted.
Use <Demo> & friends. Expect escaped HTML source, literal text and no injected element.
Try one-character learner or missing/repeated/extra query shape. Expect 400 before scope lookup; source/preview clear.
A server-side page technology for generating response content.
Literal page content contributed to the generated response.
Page-level processing configuration such as encodings.
A declaration connecting a prefix to a tag library.
A language for evaluating model values and expressions in supported contexts.
An application value associated with page, request, session or application scope.
A conventional property exposed through suitable getter/setter methods.
The JSP source and source inclusions processed together for translation.
A tag-library action for operations such as output, iteration or conditional presentation.
The presentation component that renders a prepared application model.
Design a controller that validates the learner, obtains bounded course data and attaches lessonReport to request scope. Forward before committing output to a JSP under WEB-INF. The view should state its source/output encoding and compatible core tag library.
Use explicit request-scope expressions, a loop for course rows and an empty-state branch. Render learner labels and titles as HTML text with appropriate encoding. Derive counts from the accepted model instead of accepting arbitrary client totals.
Test missing, empty and malformed models, a same-name session/page collision and special-character text. Separate local model checks from actual JSP compilation, EL/JavaBean lookup, tag-library resolution and HTTP response checks.
Success criterion: explain which scope produced the report and why the generated source and visible text are both correct. Next: Level 25 — JDBC and Database Connectivity.
Explain JSP’s server-side role, directives, EL and core tags; reproduce qualified/unqualified lookup differences and distinguish empty from missing/bad models. Identify the real-runtime checks this browser lab cannot perform. Completion is a local study marker.