Servlets

Servlets live to service clients, its job is to take a client's request and send back a response. The request carries crucial data, and your servlet code has to know how to find it and how to use it. The response carries the info the browser needs to render a page and your servlet code has to know how to send it, it can decide to send it to something else (another page, servlet, JSP) instead.

The servlet creates the request and response objects, creates or allocates a new thread for the servlet and calls the servlets service() method, passing the request and response references as arguements.

The servlet has only one main state initialized, if it isn't initialized then it's either being initialized (running its constructor or init() method) or being destroyed (running its destroy() method) or it simply does not exist. The following is what happens when you initialize a servlet

Servlets Life Cycle

The servlet herits a number of lifecycle methods

Servlet Interface
(javax.servlet.Servlet)

This interface makes sure that the following five methods have been implmented

service(ServletRequest, ServletResponse)
init(ServletConfig)
destroy()

getServletConfig()
getServletInfo()

GenericServlet Class
(javax.servlet.GenericServlet)

This class is an abstract class that implements most of the basic servlet method you will need, it has the following methods

service(ServletRequest, ServletResponse)
init(ServletConfig)

init()
destroy()
getServletConfig()
getServletInfo()
getInitParameter()
getInitParameterNames()
getServletContext()
log(String)
log(String,Throwable)

HttpServlet Class
(javax.servlet.http.HttpServlet)
This class is also an abstract class which implements the service() method to reflect the HTTPness of the servlet, it will only take HTTP-specific request and response

service(HttpServletRequest, HttpServletResponse)
service(ServletRequest, ServletResponse)
doGet(HttpServletRequest, HttpServletResponse)
doPost(HttpServletRequest, HttpServletResponse)
doHead(HttpServletRequest, HttpServletResponse)
doOptions(HttpServletRequest, HttpServletResponse)
doPost(HttpServletRequest, HttpServletResponse)
doTrace(HttpServletRequest, HttpServletResponse)
doDelete(HttpServletRequest, HttpServletResponse)
getLastModified(HttpServletRequest)
YourServlet
(uk.co.datadisk.foo)

This is your own class but most of the servletness is handled by the superclass methods, all you do is override the HTTP methods you need.

doPost(HttpServletRequest, HttpServletResponse)
yourOwnMethod()

The big moments of a servlet's life are the following

  When is it called Whats it for Do you override it
init()

The container calls init() on the servlet instance after the servlet instance is created but before the servlet can service any clients request.

It always completes before moving onto service() method

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

If you have initialization code (connecting to a database) then you will override the init() method
service() When the first client request comes in, the Container starts a new thread or allocates a thread from a pool and causes the servlet's service() method to be invoked This method looks at the request, determines the HTTP method(GET, POST, etc)and invokes the matching doGet(), doPost() method No, Very unlikely

You should NOT override the service() method. Your job is to override the doGet(), doPost() methods and let the service() implemenation from HTTPServlet worry about calling the right one
doGet() and doPost() The service() method invokes these methods based on the HTTP request. This is where your code begins (its a bit like the main() method)

Always override at least ONE of doGet() or doPost()

You can call each other to cover both options, for example doGet() could call doPost() method which has the code

The container run multiple threads to process multiple requests to a single servlet, so each client gets a separate thread for each request and the Container allocates new request and response objects.

Request and Response is the key to everything and the arguements to the service(), below is some of the methods that they use

HTTP Methods

I mentioned above that there are a number of HTTP methods, here is the complete list

A GET is not supposed to change anything on a server, as its name applies it is only suppose to GET information, POST of the other hand is suppose to change data on the server, this is because you normally send data with POST. Because of this GET by the HTTP definition is called idempotent and POST is called NOT idempotent. A classic example is if you buy something on the internet and you pay for it, but after you have paid for it the browser does not response with a complete page, deciding that the first transaction did not complete you then pay for again, this is because the POST data (shopping cart) was resent again.

So how do you specify which one you use, you explicitly say within the code i.e. method="GET", but what if the code does not explicitly say which one to use, then by default a GET is sent, this can also throw an error in your application if you have not created a doGet() method. Remember if you do not specify which method you are using GET is used by default.

Most developers will incorporate the doGet() method within the doPost() method

incorporate doGet into doPost public void doPost(...) throws ... {
  doGet(request, response);
}

When you send parameters to the doPost() method you use the request.getParameter() method to obtain the values

retrieving parameters from HTTP POST

//The HTTP body will send this
type=froffy&size=grande

//The doPost will retrieve the values as below
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
  
  String typeParam = request.getParameter("type"):
  String sizeParam = request.getParameter("size");
}

The Request Object

There are many things that you can get from a Request Object, the most common i have listed below, but I will leave you to the internet (Google) to find out more information.

The Response Object

The response is what goes back to the browser, you normally get a output stream (normally a writer) and use that stream to write your HTML code, which goes back to the browser. Normally you would never write HTML code in a response Object because you would use JSP rather than send back HTML. However you can send back other things other an HTTP code, like JAR files, Images, Sound files, Video, etc. They only thing you need to let the request is what type of data you are sending back, this helps the browser at the other end to interpret the data, for example if you send back some video it can open a media player to play the video. So how do you let the browser know, by telling the browser the MIME type (content type) within the HTTP header.

Letting the browser know what data you are sending back response.setContentType("application/jar");
response.setContentType("video/quicktime");
response.setContentType("image/jpeg");

There are many MIME types, so I will leave you to the internet (Google) to find the one you are after.

The ServletResponse interface gives you only two output streams that you can use

PrintWriter PrintWriter writer = response.getWriter();

writer.println("some HTML text");

Note: this is used for print text data to a character stream
OutputStream ServletOutputStream out = response.getOutputStream();

out.write(aByteArray);

Note: this is used to write anything other than text data.

You can add and set Response headers using the ServletResponse interface, basically it uses a header/value pair to create of set headers. The difference between set and add shows up when the header is there, the format is (<header>,<value>)

setHeader

response.setHeader("foo","bar");

addHeader response.addHeader("foo", "bar");

You can also let something else handle the response, you can either redirect it or dispatch the request to some other component in your web app (typically a JSP), however you must do this before the response has been sent.

redirect the Response response.sendRedirect("http://www.datadisk.co.uk");

Note: the sendRedirect takes a String object not a URL type of object.

While a redirect makes the clients browser do all the work, a request dispatch makes something on the server do the work.

dispatch the response RequestDispatcher view = request.getRequestDispatcher("result.jsp");
view.forward(request,response);

Note: the JSP will now takes over the response