The Three Big Lifecycle Moments

1 init()

When it’s called

The Container calls init() on the servlet instance after the servlet instance is created but before the servlet can service any client requests.

What it’s for

Gives you a chance to initialize your servlet before handling any client requests.

Do you override it? Possibly.

If you have initialization code (like getting a database connection or registering yourself with other objects), then you’ll override the init() method in your servlet class.

2 service()

When it’s called

When the first client request comes in, the Container starts a new thread or allocates a thread from the pool, and causes the servlet’s service() method to be invoked.

What it’s for

This method looks at the request, determines the HTTP method (GET, POST, etc.) and invokes the matching doGet(), doPost(), etc. on the servlet.

Do you override it?

No. Very unlikely.

You should NOT override the service() method. Your job is to override the doGet() and/or doPost() methods and let the service() implementation from HTTPServlet worry about calling the right one.

3 doGet() and/or doPost()

When it’s called

The service() method invokes doGet() or doPost() based on the HTTP method (GET, POST, etc.) from the request.

(We’re including only doGet() and doPost() here, because those two are probably the only ones you’ll ever use.)

What it’s for

This is where your code begins! This is the method that’s responsible for whatever the heck your web app is supposed to be DOING.

You can call other methods on other objects, of course, but it all starts from here.

Do you override it? ALWAYS at least ONE of them! (doGet() or doPost())

Whichever one(s) you override tells the Container what you support. If you don’t override doPost(), for example, then you’re telling the Container that this servlet does not support HTTP POST requests.

image with no caption

The service() method is always called in its own stack...

Servlet initialization

Client request 1

Client request 2

Thread A

Thread B

Thread C

The Container calls init() on the servlet instance after the servlet instance is created but before the servlet can service any client requests.

If you have initialization code (like getting a database connection or registering yourself with other objects), then you’ll override the init() method in your servlet class. Otherwise, the init() method from GenericServlet runs.

When the first client request comes in, the Container starts (or finds) a thread and causes the servlet’s service() method to be invoked.

You normally will NOT override the service() method, so the one from HttpServlet will run. The service() method figures out which HTTP method (GET, POST, etc.) is in the request, and invokes the matching doGet() or doPost() method. The doGet() and doPost() inside HttpServlet don’t do anything, so you have to override one or both. This thread dies (or is put back in a Container-managed pool) when service() completes.

When the second (and all other) client requests come in, the Container again creates or finds a another thread and causes the servlet’s service() method to be invoked.

So, the service() --> doGet() method sequence happens each time there’s a client request. At any given time, you’ll have at least as many runnable threads as there are client requests, limited by the resources or policies/configuration of the Container. (You might, for example, have a Container that lets you specify the maximum number of simultaneous threads, and when the number of client requests exceeds that, some clients will just have to wait.)

Get Head First Servlets and JSP, 2nd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.