Servlets and JavaServer Pages (JSP) remain foundational technologies for building dynamic, server-side web applications in the Java ecosystem. Though newer frameworks have emerged, understanding these core components provides critical insight into request handling, view rendering, and state management in traditional Java EE and Jakarta EE web applications.
Understanding Servlets
A servlet is a Java class that extends HttpServlet and responds to HTTP requests. It operates within a servlet container (e.g., Tomcat or Jetty), which manages its lifecycle and dipsatches incoming requests based on URL patterns.
Lifecycle Overview
- Initialiaztion: The container calls
init()once after instantiation. - Request Processing: For each matching HTTP request,
service()delegates todoGet(),doPost(), etc., depending on the method. - Termination:
destroy()runs before unloading, allowing cleanup of resources.
Minimal Servlet Example
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/greet")
public class GreetingServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
res.getWriter().printf("<h1>Greetings from %s</h1>",
this.getClass().getSimpleName());
}
}
Working with JSP
JSP files are text-based templates that combine static markup (HTML, XML) with dynamic scripting elements. At runtime, the container compiles each JSP into a servlet class—meaning JSPs inherit all servlet capabilities while offering a more HTML-friendly syntax.
Basic JSP Syntax
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head><title>Dynamic Page</title></head>
<body>
<h1>Current Timestamp</h1>
<p><%= new java.time.LocalDateTime().toString() %></p>
</body>
</html>
Integrating Servlets and JSP
A common pattern is to use servlets for logic and control flow, then forward processed data to JSP for presentation. This separation supports the Model-View-Controller (MVC) principle.
Data Passing Example
A servlet prepares data and forwards it to a JSP:
@WebServlet("/dashboard")
public class DashboardController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
req.setAttribute("pageTitle", "User Dashboard");
req.setAttribute("activeUsers", 42L);
req.getRequestDispatcher("/WEB-INF/views/dashboard.jsp").forward(req, res);
}
}
The corresponding JSP (located under /WEB-INF/views/ for security):
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head><title>${pageTitle}</title></head>
<body>
<h1>${pageTitle}</h1>
<p>Active users: ${activeUsers}</p>
</body>
</html>
State Management Across Requests
HTTP is stateless, so maintaining user context requires explicit mechanisms. The HttpSession interface offers session-scoped storage tied to a client via cookies or URL rewriting.
// In a login servlet
HttpSession session = request.getSession(true);
session.setAttribute("currentUser", userObject);
session.setMaxInactiveInterval(1800); // 30 minutes
// Later, in another servlet
User current = (User) session.getAttribute("currentUser");
Enhancing Functionality with Filters
Filters intercept requests and responses before they reach servlets or leave them. They’re ideal for cross-cutting concerns like authentication, logging, or encoding.
@WebFilter("/admin/*")
public class AdminAccessFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpSession session = request.getSession(false);
if (session != null && "ADMIN".equals(session.getAttribute("role"))) {
chain.doFilter(req, res);
} else {
HttpServletResponse response = (HttpServletResponse) res;
response.sendError(HttpServletResponse.SC_FORBIDDEN);
}
}
}
Modernizing JSP with Tag Libraries
JSTL (JavaServer Pages Standard Tag Library) replaces scriptlets with declarative tags, improving readability and reducing embedded Java code.
<%@ taglib prefix="c" uri="http://jakarta.ee/xml/ns/jakartaee" %>
<c:choose>
<c:when test="${not empty items}">
<ul>
<c:forEach var="item" items="${items}">
<li>${item.name}</li>
</c:forEach>
</ul>
</c:when>
<c:otherwise>
<p>No items available.</p>
</c:otherwise>
</c:choose>