Question

JSF vs Servlet vs JSP: Differences and Relationships in Java Web Development

javajspjsfservletsjakarta-ee

Question

How are JavaServer Pages (JSP) and Servlets related to one another? Is a JSP ultimately a type of Servlet?

How does JavaServer Faces (JSF) relate to JSP? Is JSF a prebuilt, UI-focused form of JSP, similar to ASP.NET MVC?

Please explain the roles of Servlet, JSP, and JSF in a Java web application and when each is used.

Short Answer

Servlets, JSP, and JSF all belong to the Java web ecosystem, but they solve different problems. Servlets handle HTTP requests and responses, JSP was designed to render server-side HTML views, and JSF is a component-based UI framework for building web forms and screens. By the end, you will understand their relationships, the request flow, and why modern JSF applications normally use Facelets rather than JSP.

Concept

A Java web application receives HTTP requests, runs server-side code, and returns HTTP responses—usually HTML. Servlet, JSP, and JSF participate at different layers of that process.

  • Servlet: A Java class managed by a servlet container such as Tomcat. It receives HTTP requests and creates HTTP responses. A servlet is low-level but flexible.
  • JSP (JavaServer Pages): A server-side view technology for generating HTML. A JSP file is translated and compiled by the server into a Servlet. Therefore, a JSP is not a servlet source file that you normally write as Java, but it eventually runs as a generated servlet.
  • JSF (JavaServer Faces): A server-side, component-based web framework. It provides UI components such as input fields, buttons, tables, validation, conversion, and navigation. JSF requests are usually handled by a central servlet called FacesServlet.

JSP and JSF are not the same type of technology:

  • JSP focuses on writing HTML templates that can display server-provided data.
  • JSF focuses on building a UI from reusable components and managing form submission, validation, and UI state.

Historically, JSF could use JSP as a view declaration language. However, JSP was a poor fit for JSF's component lifecycle. Modern JSF applications normally use Facelets (.xhtml) as their view technology, not JSP.

JSF is also not simply “prebuilt JSP.” It is closer to a full UI framework: it processes requests through a lifecycle, restores/builds a component tree, validates submitted values, updates model values, invokes application actions, and renders the response. The broad architectural idea has similarities to other server-side MVC-style UI frameworks, but its programming model and lifecycle are specifically JSF's own.

Mental Model

Think of a restaurant:

  • A Servlet is the waiter who receives an order (HTTP request), decides what should happen, and delivers the result (HTTP response).
  • A JSP is a printable menu template. The server fills it with current data, such as a user's name or a list of products, to create HTML.
  • JSF is a restaurant ordering system with ready-made controls: menus, quantity fields, validation rules, and checkout buttons. It tracks the interaction process and coordinates the screens.

A JSP is converted into a servlet behind the scenes, much like turning a template into an executable process. JSF itself uses a servlet (FacesServlet) as its entry point, but JSF adds much more behavior above ordinary servlet request handling.

Take Quiz

Syntax and Examples

A basic servlet extends HttpServlet and writes an HTTP response.

import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().println("<h1>Hello from a Servlet</h1>");
    }
}

A JSP is usually better for HTML that contains dynamic values. A servlet can place data in the request and forward to the JSP.

// Inside a servlet method
request.setAttribute("username", "Amina");
request.getRequestDispatcher("/WEB-INF/views/welcome.jsp")
       .forward(request, response);
<%-- /WEB-INF/views/welcome.jsp --%>
<%@ page contentType="text/html;charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <title>Welcome</title>
</head>
<body>
    <h1>Welcome, ${username}!</h1>
</body>
</html>

The ${username} expression uses Expression Language (EL) to read the username request attribute. When the JSP is first requested or changed, the container translates it into Java servlet code and compiles it.

A modern JSF view typically uses Facelets and XHTML:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="jakarta.faces.html">
<h:head>
    <title>JSF Greeting</title>
</h:head>
<h:body>
    <h:form>
        <h:outputLabel for="name" value="Your name:" />
        <h:inputText id="name" value="#{greetingBean.name}" required="true" />
        <h:commandButton value="Greet" action="#{greetingBean.greet}" />
        <h:message for="name" />
        <h:outputText value="#{greetingBean.message}" />
    </h:form>
</h:body>
</html>

Here, tags such as <h:inputText> represent JSF UI components, not ordinary HTML text inputs. JSF connects them to a Java backing bean, validates the form, and renders the final HTML.

Step by Step Execution

Consider a traditional servlet-and-JSP request flow:

@WebServlet("/profile")
public class ProfileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response)
            throws ServletException, IOException {

        String displayName = "Jordan";
        request.setAttribute("displayName", displayName);
        request.getRequestDispatcher("/WEB-INF/views/profile.jsp")
               .forward(request, response);
    }
}
<%@ page contentType="text/html;charset=UTF-8" %>
<h1>Profile: ${displayName}</h1>

When a browser requests /profile:

  1. The servlet container finds ProfileServlet because of @WebServlet("/profile").
  2. It calls doGet() for this GET request.
  3. The servlet creates or obtains application data. This example uses the string "Jordan".
  4. request.setAttribute() makes that data available during the current request.
  5. forward() transfers control internally to profile.jsp. The browser does not make a second request.
  6. The JSP evaluates ${displayName} and produces <h1>Profile: Jordan</h1>.
  7. The JSP-generated servlet writes the HTML response.
  8. The browser receives and displays the HTML.

For a JSF form submission, FacesServlet handles the request. JSF restores or builds its component tree, converts and validates submitted values, updates the backing bean, invokes an action method, and renders the view again.

Real World Use Cases

  • Servlets

    • Implement a small HTTP endpoint.
    • Stream a generated CSV, PDF, or file download.
    • Handle a callback from a payment provider or another service.
    • Add low-level request handling where a full web framework is unnecessary.
  • JSP

    • Maintain a legacy server-rendered Java application.
    • Render administrative pages with data prepared by servlets or controllers.
    • Build simple HTML views where request attributes are displayed with EL and tag libraries.
  • JSF

    • Build internal business applications with many data-entry forms.
    • Create screens requiring server-side conversion and validation, such as dates, amounts, and required fields.
    • Use reusable UI components for tables, dialogs, forms, and navigation.
    • Develop applications on Jakarta EE platforms where JSF and related APIs are already available.

In many newer Java applications, teams may choose other tools, such as Spring MVC with Thymeleaf or a JavaScript frontend with REST APIs. The core servlet API still underpins many server-side Java web technologies.

Take Quiz

Real Codebase Usage

In a servlet-and-JSP codebase, developers usually separate responsibilities:

  • A servlet/controller validates request parameters and calls application services.
  • The servlet stores view data as request attributes.
  • The JSP renders HTML and avoids business logic.
  • JSP files are often stored under WEB-INF so users cannot request them directly; only a servlet/controller forwards to them.

A useful servlet guard-clause pattern is:

String id = request.getParameter("id");
if (id == null || id.isBlank()) {
    response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing id");
    return;
}

This stops invalid requests before the rest of the handler runs.

In a JSF codebase, developers commonly:

  • Bind a view to a backing bean using expressions such as #{orderBean}.
  • Put input validation near the UI with required="true", converters, validators, or Bean Validation annotations.
  • Use action methods for user events, such as saving or deleting an entity.
  • Keep database and business rules in services rather than placing them in the view.
  • Reuse components and templates through Facelets.

Even in JSF, developers should avoid putting complex business logic directly in XHTML pages or backing beans. The framework manages UI concerns; services should handle domain work.

Common Mistakes

Treating JSP as a normal Java class

A JSP eventually becomes a servlet, but you generally do not extend HttpServlet inside a JSP. Write a JSP as a view template, and let the container generate its servlet.

Putting Java scriptlets in JSP

Older JSP pages often contain Java code like this:

<% String name = request.getParameter("name"); %>
<h1>Hello <%= name %></h1>

Avoid this style in new code. It mixes request handling, logic, and presentation. Prefer a servlet/controller plus EL:

request.setAttribute("name", name);
request.getRequestDispatcher("/WEB-INF/views/hello.jsp").forward(request, response);
<h1>Hello ${name}</h1>

Assuming JSF uses JSP by default

Modern JSF views are normally Facelets .xhtml files. Do not start a new JSF project with JSP unless you are specifically maintaining an old application with that setup.

Writing raw HTML response strings for a large page

This works for a tiny response but becomes difficult to maintain:

response.getWriter().println("<h1>Dashboard</h1>");

Use a view technology or a frontend template for substantial pages.

Expecting a redirect and a forward to behave the same way

  • forward() stays on the server and keeps the same request attributes.
  • sendRedirect() tells the browser to make a new request, so request attributes are lost.

Confusing JSF components with plain HTML

<h:inputText> is a JSF component with server-side state and validation behavior. It is not merely a shorter spelling of <input type="text">.

Comparisons

TechnologyMain roleTypical unit you writeRequest handlingView rendering
ServletLow-level HTTP handlingJava class extending HttpServletYour doGet, doPost, and related methodsYou write response output or forward elsewhere
JSPServer-side HTML view template.jsp fileUsually receives data from a servlet/controllerGenerates HTML; compiled to a servlet
JSFComponent-based server-side UI frameworkFacelets .xhtml view plus Java backing beanFacesServlet and the JSF lifecycleRenders a UI component tree as HTML
ChoiceBest fitTrade-off
Servlet aloneSmall endpoints, downloads, custom HTTP behaviorHTML becomes cumbersome if written as Java strings
Servlet + JSPTraditional server-rendered pages with clear controller/view separationMore manual handling of forms and view behavior than JSF
JSF + FaceletsForm-heavy business UIs with reusable server-side componentsRequires understanding the JSF lifecycle and state management

JSP is related to Servlets through compilation. JSF is related to Servlets because JSF is entered through FacesServlet. JSP and JSF can both generate HTML, but they use different view models and should not be treated as interchangeable.

Take Quiz

Cheat Sheet

  • Servlet: Java code that handles HTTP requests and responses.
  • JSP: HTML-oriented server-side template; the container compiles it into a servlet.
  • JSF: Component-based UI framework; it commonly uses Facelets .xhtml views.
  • FacesServlet: The servlet that receives JSF requests.
  • JSP is not modern JSF's usual view technology: use Facelets for new JSF views.
  • Forward to a JSP when a servlet has prepared view data:
request.setAttribute("key", value);
request.getRequestDispatcher("/WEB-INF/views/page.jsp").forward(request, response);
  • Read an attribute in JSP:
${key}
  • Forward vs redirect:
    • forward() keeps one request and its attributes.
    • sendRedirect() causes a new browser request.
  • Keep business logic out of JSP pages and JSF views.

FAQ

Is JSP a servlet?

Not directly in source form. A JSP is a template that the servlet container translates and compiles into a servlet class before it runs.

Does JSF replace servlets?

No. JSF runs through FacesServlet, which is itself a servlet. JSF provides a higher-level UI framework so you usually do not write a servlet for every JSF page.

Does JSF use JSP?

Older JSF versions could use JSP, but modern JSF applications normally use Facelets with .xhtml files. Facelets is designed for JSF's component model.

Should I use JSP for a new JSF application?

No. Use Facelets unless you are maintaining an older application that already uses JSP.

Can a servlet forward to a JSP?

Yes. This is a classic Java web application pattern: the servlet handles the request and the JSP renders the response.

Can JSP call a database directly?

It technically can through embedded Java code, but it is poor design. Keep database access in services or data-access code, and pass prepared data to the JSP.

Is JSF the same as MVC?

JSF supports separation between UI views, backing beans, and application logic, but it is specifically a component-based framework with its own request-processing lifecycle. It is not merely a JSP-based version of MVC.

Are these technologies still relevant after Java EE became Jakarta EE?

Yes. The APIs continue under Jakarta EE names, such as jakarta.servlet and jakarta.faces. Older projects may still use the former javax.* package names.

Take Quiz

Mini Project

Description

Build a small profile page using the classic Servlet + JSP separation. The servlet receives a query parameter, validates it, and passes display data to a JSP. This demonstrates how servlets control request flow while JSP focuses on rendering HTML.

Goal

Create a /profile page that displays a validated user name supplied through a query parameter.

Requirements

Requirement 1

Take Quiz

Keep learning

Related questions

View more