The servlet starts life when the Container finds the servlet class file. This virtually always happens when the Container starts up (for example, when you run Tomcat). When the Container starts, it looks for deployed web apps and then starts searching for servlet class files. (In the Deployment chapter, we’ll go into more details of how, why, and where the Container looks for servlets.)
Finding the class is the first step.
Loading the class is the second step, and it happens either on Container startup or first client use. Your Container might give you a choice about class loading, or it might load the class whenever it wants. Regardless of whether your Container gets the servlet ready early or does it just-in-time when the first client needs it, a servlet’s service() method will not run until the servlet is fully initialized.
Your servlet is always loaded and initialized BEFORE it can service its first client request.
init() always completes before the first call to service()
Why is there an init() method? In other words, why isn’t the constructor enough for initializing a servlet?
What kind of code would you put in the init() method?
Hint: the init() method takes an object reference argument. What do you think the argument to the init() method might be, and how (or why) would you use it?
A servlet moves from does not exist to initialized (which really means ready to service client requests), beginning with a constructor. But the constructor makes only an object, not a servlet. To be a servlet, the object needs to be granted servletness.
When an object becomes a servlet, it gets all the unique privileges that come with being a servlet, like the ability to use its ServletContext reference to get information from the Container.
Why do we care about initialization details?
Because somewhere between the constructor and the init() method, the servlet is in a Schroedinger’s servlet state. You might have servlet initialization code, like getting web app configuration info, or looking up a reference to another part of the application, that will fail if you run it too early in the servlet’s life. It’s pretty simple though, if you remember to put nothing in the servlet’s constructor!
There’s nothing that can’t wait until init().
A ServletConfig object
One ServletConfig object per servlet.
Use it to pass deploy-time information to the servlet (a database or enterprise bean lookup name, for example) that you don’t want to hard-code into the servlet (servlet init parameters).
Use it to access the ServletContext.
Parameters are configured in the Deployment Descriptor.
One ServletContext per web app. (They should have named it AppContext.)
Use it to access web app parameters (also configured in the Deployment Descriptor).
Use it as a kind of application bulletin-board, where you can put up messages (called attributes) that other parts of the application can access (way more on this in the next chapter).
Use it to get server info, including the name and version of the Container, and the version of the API that’s supported.
Don’t confuse ServletConfig parameters with ServletContext parameters!
We don’t really talk about these until the next chapter, but so many people get them confused that we want to plant the seed early: pay attention to the differences.
Start by looking at the names:
ServletConfig has the word “config” in it for “configuration”. It’s about deploy-time values you’ve configured for the servlet (one per servlet). Things your servlet might want to access that you don’t want to hard code, like maybe a database name.
ServletConfig parameters won’t change for as long as this servlet is deployed and running. To change them, you’ll have to redeploy the servlet.
ServletContext should have been named AppContext (but they didn’t listen to us), because there’s only one per web app, NOT one per servlet. Anyway, we’ll get into all this in the next chapter—this is just a heads-up.
In the next chapter we’ll look at ServletConfig and ServletContext, but for now, we’re digging into details of the request and response. Because the ServletConfig and ServletContext exist only to support your servlet’s One True Job: to handle client requests! So before we look at how your context and config objects can help you do your job, we have to back up a little and look at the fundamentals of the request and response.
You already know that you’re handed a request and response as arguments to the doGet() or doPost() method, but what powers do those request and response objects give you? What can you do with them and why do you care?
HttpServletRequest interface adds the methods that relate to the HTTP protocol... what your servlet uses to communicate with the client/browser.
Same thing with the response... the HttpServletResponse adds methods you care about when you’re using HTTP—things like errors, cookies, and headers.
The exam doesn’t expect you to know how to develop with non-HTTP servlets.
You’re not expected to know anything about how you might use servlets with a protocol other than HTTP. You are, however, still supposed to know how the class hierarchy works. So you DO have to know that HttpServletRequest and HttpServletResponse extend from ServletRequest and ServletResponse, and that most of an HttpServlet’s implementation actually comes from GenericServlet.
But that’s it. The exam assumes you’re an HttpServlet developer.
 If your quantum mechanics is a little rusty—you might want to do a Google search on “Schroedinger’s Cat”. (Warning: pet lovers, just don’t go there.) When we refer to a Schroedinger state, we mean something that is neither fully dead or fully alive, but in some really weird place in between.
 The request and response objects are also arguments to the other HttpServlet methods that you write—doGet(), doPost(), etc.