Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Learn › Spring › Web MVC

Servlets

How an HTTP request reaches Java code

What a browser sends is an HTTP request made of text. A servlet container such as Tomcat reads that text, turns it into Java objects, and calls the method of the servlet that is mapped to the path. A servlet is a Java class that "receives a request object and writes to a response object".

Checked against real execution · 48 different requests were sent to Tomcat 11.0.24 and Spring Boot 4.1.1 and checked against the results

Concepts in this lab

Servlet and servlet container
A servlet is the Java standard interface that receives an HTTP request, processes it, and produces a response. A servlet container (such as Tomcat) accepts network connections, parses requests, calls the right servlet, and manages the servlet lifecycle and the request-handling threads. Spring MVC runs on top of a single servlet called DispatcherServlet.
DispatcherServlet and the front controller pattern
This is the servlet in Spring MVC that receives every HTTP request first. It coordinates the whole flow: it finds and calls the controller that handles the request, and it turns the result into a response. A structure like this, in which a single entry point receives all requests, does the common processing, and then hands each request to the part responsible for it, is called the front controller pattern.
Embedded server
This is a web server (Tomcat by default) that is included inside a Spring Boot application and runs together with it. You can run the application with a single java -jar command, without the steps of installing a server separately and deploying the application to it.
Web server and application server
A web server is a program that receives HTTP requests and either responds with static files such as images and HTML or forwards the requests to another server (Nginx, Apache). An application server (web application server) is a program that runs program code and builds a result for each request (Tomcat). A common setup puts a web server in front and passes requests on to the application server.
Tomcat's threading model
Tomcat manages its request processing threads in a pool, and one thread takes one request and handles it until the response is finished. The number of requests it can handle at the same time is limited by the maximum number of threads (200 by default), and when all threads are in use, new requests wait. A thread stays occupied even while the request is waiting on a database or an external call.
HTTP methods
The part of an HTTP request that indicates the action the request wants to perform on a resource. GET means read, POST means create or a processing request, PUT means replace the whole resource, PATCH means modify part of it, and DELETE means delete. Use each one according to its meaning so that HTTP behavior such as caching and retries works as expected.

Try these

Running with the default settings

  1. The server starts. Tomcat listens for connections on port 8080 and builds a table of "which servlet handles which path". It registers HelloServlet, which is annotated with @WebServlet("/hello"), as the servlet for /hello. The servlet object has not been created yet.
  2. Request #1: The browser connects to the server and sends an HTTP request. What it sends is a few lines of text, like the ones shown on the screen.
  3. Tomcat assigns a thread from its thread pool and parses the text it received into an HttpServletRequest object. It also creates an empty HttpServletResponse object to hold the response. The servlet does not have to parse the text itself. It only has to read the values from this object.
  4. Tomcat looks in the table for the servlet mapped to the path /hello. It is HelloServlet.
  5. Tomcat creates the HelloServlet object at the first request. The developer does not create it with new. The container does. This one object is used until the server shuts down.
  6. HelloServlet.init() is called once. This is where the servlet does the setup it needs before it receives requests.
  7. Tomcat calls service(request, response) of HelloServlet. service() looks at the HTTP method of the request and calls doGet().
  8. doGet() runs the code that we wrote. It reads name from request and writes the status and the body to response.
  9. The method of the servlet has finished. Tomcat turns the content of the HttpServletResponse into the text of an HTTP response and sends it to the browser. It discards the request and response objects used for this request and returns the thread to the pool. The HelloServlet object stays as it is and waits for the next request.
  10. Request #2: The browser connects to the server and sends an HTTP request. What it sends is a few lines of text, like the ones shown on the screen.
  11. Tomcat assigns a thread from its thread pool and parses the text it received into an HttpServletRequest object. It also creates an empty HttpServletResponse object to hold the response. The servlet does not have to parse the text itself. It only has to read the values from this object.
  12. Tomcat looks in the table for the servlet mapped to the path /hello. It is HelloServlet.
  13. The HelloServlet object already exists. Tomcat does not create a new one and uses that object again. It does not call init() again either.
  14. Tomcat calls service(request, response) of HelloServlet. service() looks at the HTTP method of the request and calls doGet().
  15. doGet() runs the code that we wrote. It reads name from request and writes the status and the body to response.
  16. The method of the servlet has finished. Tomcat turns the content of the HttpServletResponse into the text of an HTTP response and sends it to the browser. It discards the request and response objects used for this request and returns the thread to the pool. The HelloServlet object stays as it is and waits for the next request.
  17. The server shuts down. Tomcat calls destroy() of HelloServlet once and then discards the object. This is the chance to clean up the resources that were opened.

Result of this run

Code

@WebServlet(urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {

    @Override
    public void init() {                       // once, right after the object is created
        // setup work
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        String name = req.getParameter("name");   // read from the request
        resp.setContentType("text/plain; charset=UTF-8");
        resp.getWriter().write("Hello, " + name);   // write to the response
    }

    @Override
    public void destroy() { }                  // once, when the server shuts down
}

Assumptions of this model

The model assumes that the servlet container is Tomcat and that requests arrive one at a time, in order. Three points follow the Jakarta Servlet specification and the documentation of HttpServlet: only one servlet object is created per servlet declaration, init and destroy are each called once, and a doPost that is not overridden returns 405. Only the main lines of the HTTP request and response text are shown. For the 36 combinations with a directly written servlet, requests were sent to a real Tomcat 11.0.24, and for the 12 combinations on the Spring MVC side, to a real Spring Boot 4.1.1, and it was confirmed that the response code, the counts of object creation, init, and request handling calls, and the time when the object was created match the screen. In this process, two points on the Spring side were corrected to match reality. The DispatcherServlet object is created when the server starts, not at the first request (only init happens at the first request), and the 404 and 405 responses are dispatched once more to /error, so there are two request handling calls per request. Among the entries for where the response was produced, "Default servlet of Tomcat" and "Default doPost of HttpServlet" were inferred from the response code and were not observed directly.

Previous lab: Connection pool and OSIV · Next lab: Spring MVC request flow

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these