Servlet Fundamentals and Web Application Architecture

Web Application Architecture Overview

Modern web applications rely on structured communication models between clients and servers. Two foundational architectural patterns dominate this space: Client/Server (C/S) and Browser/Server (B/S).

C/S Architecture

In C/S systems, dedicated client software must be installed locally to interact with backend services. While offering rich UI capabilities—especially in domains like 3D gaming—it suffers from deployment friction: every server-side update typically requires corresponding client upgrades. Examples include desktop messaging apps such as QQ and WeChat.

B/S Architecture

The B/S model eliminates client installation by leveraging standard web browsers as universal interfaces. All logic resides on the server, making updates seamless and centralized. However, it trades off some graphical fidelity and responsiveness due to reliance on HTTP and browser rendering constraints.

Web Servers and Tomcat Deployment

A web server serves as the runtime container for dynamic web applications. Among open-source options, Apache Tomcat stands out for its lightweight footprint, Servlet/JSP compliance, and developer-friendly tooling.

Key Tomcat Directories

  • bin/: Contains startup/shutdown scripts (startup.bat, shutdown.sh)
  • conf/: Holds configuration files—server.xml (port, SSL settings) and web.xml (default servlet mappings)
  • webapps/: Deployment directory; each subfolder represents a deployable web application
  • work/: Stores compiled JSPs and temporary artifacts during execution

Basic Project Deployment

To deploy a static site:

  1. Create myapp/ under webapps/
  2. Add an HTML file (e.g., index.html) at the root
  3. Access via http://localhost:8080/myapp/index.html

Servlet Development Essentials

A Servlet is a Java class that handles HTTP requests dynamically. It forms the backbone of Java-based web applications and adheres to the javax.servlet.Servlet interface.

Minimal Servlet Implementation

Instead of implementing all five interface methods manually, modern practice favors extending HttpServlet:

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;

public class GreetingServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setContentType("text/plain;charset=UTF-8");
        resp.getWriter().println("Hello from Servlet at " + LocalDateTime.now());
    }
}

Declarative Configuration with Annotations

Since Servlet 3.0, annotations simplify mapping without XML:

@WebServlet("/greet")
public class GreetingServlet extends HttpServlet {
    // implementation as above
}

HTTP Protocol Foundations

HTTP operates over TCP and follows a stateless request-response paradigm. Key characteristics include:

  • Statelessness: Each request carries full context; no built-in memory of prior interactions
  • Connection handling: HTTP/1.1 uses persistent connections by default (Connection: keep-alive)
  • Message structure: Requests contain method, URI, headers, and optional body; responses include status line, headers, and payload

Request and Response Handling

Two core objects mediate client-server interaction:

HttpServletRequest

Provides access to request data:

  • getParameter(String name): Retrieves form or query string values
  • getHeader(String name): Reads HTTP headers (e.g., User-Agent)
  • getSession(): Obtains or creates session state

HttpServletResponse

Controls output delivery:

  • setContentType(String type): Declares MIME type and encoding (e.g., "text/html;charset=UTF-8")
  • getWriter(): Returns a PrintWriter for text content
  • sendRedirect(String location): Triggers client-side redirection

Data Flow Patterns: Forward vs Redirect

Controlling navigation within the server involves two distinct mechanisms:

Request Forwarding

Occurs entirely on the server side using RequestDispatcher. The browser URL remains unchanged, and request-scoped attributes persist across the forward:

req.setAttribute("message", "Processed successfully");
req.getRequestDispatcher("/result.jsp").forward(req, resp);

Client-Side Redirection

Issues an HTTP 302 response instructing the browser to make a new request. This changes the address bar and discards request-scoped data:

resp.sendRedirect("/success.html");

State Management Strategies

Because HTTP is inherently stateless, applications use several techniques to maintain context:

Cookies

Small key-value pairs stored on the client and sent with each request to the same domain:

// Setting a cookie
Cookie userPref = new Cookie("theme", "dark");
userPref.setPath("/");
userPref.setMaxAge(60 * 60 * 24); // 1 day
resp.addCookie(userPref);

// Reading cookies
Cookie[] cookies = req.getCookies();
if (cookies != null) {
    for (Cookie c : cookies) {
        if ("theme".equals(c.getName())) {
            System.out.println("Theme: " + c.getValue());
        }
    }
}

HTTP Session

Server-managed state tied to a unique session ID, typically stored in a cookie. Sessions survive multiple requests from the same browser:

HttpSession session = req.getSession();
session.setAttribute("userRole", "admin");
String role = (String) session.getAttribute("userRole");

Filter-Based Cross-Cutting Concerns

Filters intercept requests before they reach servlets, enabling reusable logic like authentication or character encoding:

@WebFilter("/secure/*")
public class AuthFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute("user") == null) {
            ((HttpServletResponse) resp).sendRedirect("/login");
            return;
        }
        chain.doFilter(req, resp);
    }
}

Application Lifecycle and Scoping

Three primary scopes govern object lifetime in servlet containers:

  • Request scope: Valid only for the duration of a single HTTP request
  • Session scope: Persists across multiple requests from the same client until timeout or invalidation
  • Application scope (ServletContext): Shared across all users and requests for the entire web application

ServletContext Usage Example

Track global metrics like total application hits:

@WebServlet("/stats")
public class StatsServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        ServletContext ctx = getServletContext();
        Integer count = (Integer) ctx.getAttribute("hitCount");
        count = (count == null) ? 1 : count + 1;
        ctx.setAttribute("hitCount", count);
        resp.getWriter().println("Total visits: " + count);
    }
}

Thẻ: Servlet http Tomcat java-web web-architecture

Đăng vào ngày 12 tháng 6 lúc 23:26