JSP (Java Server Pages) Basics

    Atul Kabra3 min readUpdated

    JSP (Java Server Pages) is a technology for building dynamic web pages where you write mostly HTML and drop in special tags that the server fills with live data. Behind the scenes, the container compiles each JSP file into a servlet the first time it is requested — so JSP is really servlets with a friendlier, HTML-first syntax. It exists to solve a real pain: writing HTML by hand inside out.println() calls in a servlet is ugly and error-prone.

    In short, servlets are great for logic; JSP is great for presentation.

    How JSP works under the hood

    When a browser requests home.jsp, the container:

    1. Translates the JSP file into Java servlet source code.
    2. Compiles that source into a .class file.
    3. Runs it like any other servlet to produce the HTML response.

    This happens once; subsequent requests reuse the compiled servlet, so JSP is fast after the first hit. Because of this, you can mix static HTML with dynamic values seamlessly.

    The building blocks

    Modern, well-written JSP relies on three things:

    • Expression Language (EL)${ ... } syntax to read data without Java code. Example: ${user.name}.
    • JSTL (JSP Standard Tag Library) — tags for loops, conditionals, and formatting, so you avoid raw Java in pages.
    • Directives — page-level settings like content type and tag library imports.

    You can embed raw Java in <% ... %> scriptlets, but modern practice strongly discourages this. Keep Java in your servlets and controllers; keep JSP focused on display.

    Want to learn this properly?

    Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.

    Browse courses

    A clean JSP example

    This page lists courses passed in as a request attribute. Note the Jakarta-era taglib URI:

    <%-- Page directive: set content type and enable EL --%>
    <%@ page contentType="text/html;charset=UTF-8" %>
    
    <%-- Import JSTL core tags (Jakarta namespace) --%>
    <%@ taglib prefix="c" uri="jakarta.tags.core" %>
    
    <!DOCTYPE html>
    <html>
    <head><title>Course List</title></head>
    <body>
        <h1>Available Courses</h1>
    
        <%-- c:choose handles the empty case cleanly --%>
        <c:choose>
            <c:when test="${empty courses}">
                <p>No courses available right now.</p>
            </c:when>
            <c:otherwise>
                <ul>
                    <%-- Loop over the "courses" attribute set by the servlet --%>
                    <c:forEach var="course" items="${courses}">
                        <%-- EL reads bean properties: course.getTitle() --%>
                        <li>${course.title} — ${course.durationWeeks} weeks</li>
                    </c:forEach>
                </ul>
            </c:otherwise>
        </c:choose>
    </body>
    </html>
    

    The servlet sets the data and forwards to the JSP:

    // Inside a servlet's doGet method
    request.setAttribute("courses", courseService.findAll());
    // Forward to the JSP view for rendering
    request.getRequestDispatcher("/WEB-INF/views/courses.jsp")
           .forward(request, response);
    

    Notice the JSP lives under /WEB-INF/ so it cannot be requested directly — only the servlet decides when to render it. That is the MVC pattern in miniature.

    Common mistakes

    • Using the old taglib URIs. With Jakarta EE, JSTL URIs changed to jakarta.tags.core (etc.). The legacy http://java.sun.com/jsp/jstl/core URI will not resolve in a Jakarta container.
    • Writing business logic in scriptlets. Heavy <% ... %> blocks make pages unmaintainable. Use a servlet/controller for logic and EL/JSTL for display.
    • Placing JSPs in a publicly reachable folder. Put view JSPs under /WEB-INF/ so users cannot bypass your controller by typing the URL.
    • Forgetting the page content type. Without the contentType directive, character encoding bugs (garbled accents) appear.
    • Mixing javax.* and jakarta.* libraries. Your JSTL implementation must match your container's namespace.

    FAQ

    Is JSP still used in 2026? It is mature and still maintained as part of Jakarta EE, common in existing enterprise apps. New projects often use templating engines like Thymeleaf with Spring Boot, but JSP remains valuable to understand.

    JSP vs Thymeleaf — which should I learn? Learn the concepts here first; they transfer directly. Thymeleaf is a popular modern alternative covered in Spring-focused tutorials.

    Keep learning

    JSP is the view layer that pairs with servlets. See how it all fits together in MVC architecture, or browse the full Advanced Java hub.


    Want to build complete Java web apps, view layers included? Join the waitlist for the Advanced Java course at Infoplanet, Jalgaon.

    Want to learn this properly?

    Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.

    Browse courses
    Atul Kabra

    Founder, Infoplanet

    Atul Kabra founded Infoplanet in 2001 and has spent over two decades teaching programming — C, C++, Java, databases and more — to students across Maharashtra.

    Related guides