SERVLETS Class Notes
SERVLETS Class Notes
SERVLETS Class Notes
Java Servlets is a web technology for Java. It was the first web technology for Java and many
new web technologies have arrived since. Still, Java Servlets are very useful, both to know, and
for certain use cases.
Java Servlets are part of the Java Enterprise Edition (Java EE). You will need to run your Java
Servlets inside a Servlet compatible "Servlet Container" (e.g. web server) in order for them to
work.
A servlet follows a certain life cycle. The servlet life cycle is managed by the servlet container.
The life cycle contains the following steps:
Step 1, 2 and 3 are executed only once, when the servlet is initially loaded. By default the servlet
is not loaded until the first request is received for it. You can force the container to load the
servlet when the container starts up though. See web.xml Servlet Configuration for more details
about that.
Step 4 is executed multiple times - once for every HTTP request to the servlet.
Step 5 is executed when the servlet container unloads the servlet.
Each step is described in more detail below:
The Java Servlet life cycle
Typically, only a single instance of the servlet is created, and concurrent requests to the servlet
are executed on the same servlet instance. This is really up to the servlet container to decide,
though. But typically, there is just one instance.
Call the Servlets init() Method
When a servlet instance is created, its init() method is invoked. The init() method allows a
servlet to initialize itself before the first request is processed.
You can specify init parameters to the servlet in the web.xml file. See web.xml Servlet
Configuration for more details.
As long as the servlet is active in the servlet container, the service() method can be called.
Thus, this step in the life cycle can be executed multiple times.
A servlet is unloaded by the container if the container shuts down, or if the container reloads the
whole web application at runtime.
A Java Servlet is just an ordinary Java class which implements the interface
javax.servlet.Servlet;
The easiest way to implement this interface is to extend either the class GenericServlet or
HttpServlet.
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
// do something in here
}
}
When an HTTP request arrives at the web server, targeted for your Servlet, the web server calls
your Servlet's service() method.
The service() method then reads the request, and generates a response which is sent back to
the client (e.g. a browser).
if("yes".equals(yesOrNoParam) ){
response.getWriter().write(
"<html><body>You said yes!</body></html>");
}
if("no".equals(yesOrNoParam) ){
response.getWriter().write(
"<html><body>You said no!</body></html>");
}
}
This service() method first reads the request parameter "param". Then it checks if the param is
equal to the text "yes" or "no", and writes an HTML response back to the browser.
HttpServlet
The javax.servlet.http.HttpServlet class is a slightly more advanced base class than the
GenericServlet shown in the Simple Servlet example.
The HttpServlet class reads the HTTP request, and determines if the request is an HTTP GET,
POST, PUT, DELETE, HEAD etc. and calls one the corresponding method.
To respond to e.g. HTTP GET requests only, you will extend the HttpServlet class, and
override the doGet() method only. Here is an example:
response.getWriter().write("<html><body>GET response</body></html>");
}
}
The HttpServlet class has methods you can override for each HTTP method (GET, POST etc.).
Here is a list of the methods you can override:
doGet()
doPost()
doHead()
doPut()
doDelete()
doOptions()
doTrace()
Most often you just want to respond to either HTTP GET or POST requests, so you just override
these two methods.
If you want to handle both GET and POST request from a given servlet, you can override both
methods, and have one call the other. Here is how:
doPost(request, response);
}
response.getWriter().write("GET/POST response");
}
}
I would recommend you to use the HttpServlet instead of the GenericServlet whenever
possible. HttpServlet is easier to work with, and has more convenience methods than
GenericServlet.
HttpRequest
1. javax.servlet.http.HttpRequest
2. javax.servlet.http.HttpResponse
The purpose of the HttpRequest object is to represent the HTTP request a browser sends to your
web application. Thus, anything the browser may send, is accessible via the HttpRequest.
The HttpRequest object has a lot of methods, so I will just cover the most commonly used here.
The rest you can read about in the JavaDoc, if you are interested. The parts I will cover are:
1. Parameters
2. Headers
3. InputStream
4. Session
5. ServletContext
Parameters
The request parameters are parameters that are sent from the browser along with the request.
Request parameters are typically sent as part of the URL (in the "query string"), or as part of the
body of an HTTP request. For instance:
http://jenkov.com/somePage.html?param1=hello¶m2=world
Notice the "query string" part of the URL: ?param1=hello¶m2=world This part contains two
parameters with parameter values:
param1=hello
param2=world
You can access these parameters from the HttpRequest object like this:
protected void doGet(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
You would use the same code, if the request parameters were sent in the body part of the HTTP
request. If no parameter exists with the given name, null is returned.
In general, if the browser sends an HTTP GET request, the parameters are included in the query
string in the URL. If the browser sends an HTTP POST request, the parameters are included in
the body part of the HTTP request.
Headers
The request headers are name, value pairs sent by the browser along with the HTTP request. The
request headers contain information about e.g. what browser software is being used, what file
types the browser is capable of receiving etc. In short, at lot of meta data around the HTTP
request.
You can access the request headers from the HttpRequest object like this:
The Content-Length header contains the number of bytes sent in the HTTP request body, in
case the browser sends an HTTP POST request. If the browser sends an HTTP GET request, the
Content-Length header is not used, and the above code will return null.
In general, If no header exists with the name passed to getHeader(), null is returned.
InputStream
If the browser sends an HTTP POST request, request parameters and other potential data is sent
to the server in the HTTP request body. It doesn't have to be request parameters that is sent in the
HTTP request body. It could be pretty much any data, like a file or a SOAP request (web service
request).
To give you access to the request body of an HTTP POST request, you can obtain an
InputStream pointing to the HTTP request body. Here is how it is done:
NOTE: You will have to call this method before calling any getParameter() method, because
calling the getParameter() method on an HTTP POST request will cause the servlet engine to
parse the HTTP request body for parameters. Once parsed, you cannot access the body as a raw
stream of bytes anymore.
Session
It is possible to obtain the session object from the HttpRequest object too.
The session object can hold information about a given user, between requests. So, if you set an
object into the session object during one request, it will be available for you to read during any
subsequent requests within the same session time scope.
Here is how you access the session object from the HttpRequest object:
ServletContext
You can access the ServletContext object from the HttpRequest object too. The
ServletContext contains meta information about the web application. For instance, you can
access context parameters set in the web.xml file, you can forward the request to other servlets,
and you can store application wide parameters in the ServletContext too.
Here is how you access the ServletContext object from the HttpRequest object:
As you can see, you have to first get the session object, to get access to the ServletContext
object.
HttpResponse
1. javax.servlet.http.HttpRequest
2. javax.servlet.http.HttpResponse
For instance, here is the signature of the HttpServlet.doGet() method:
The purpose of the HttpResponse object is to represent the HTTP response your web application
sends back to the browser, in response to the HTTP request the browser send to your web
application.
The HttpResponse object has a lot of methods, so I will just cover the most commonly used
here. The rest you can read about in the JavaDoc, if you are interested. The parts I will cover are:
1. Writing HTML
2. Headers
3. Content-Type
4. Writing Text
5. Content-Length
6. Writing Binary Data
7. Redirecting to a Different URL
Writing HTML
To send HTML back to the browser, you have to obtain the a PrintWriter from the
HttpResponse object. Here is how:
writer.write("<html><body>GET/POST response</body></html>");
Headers
Just like the request object, the HttpRequest can contain HTTP headers. Headers must be set
before any data is written to the response. You set a header on the response object like this:
Here is how you set the Content-Type header on the HttpResponse object:
response.setHeader("Content-Type", "text/html");
Writing Text
You can write text back to the browser instead of HTML, like this:
response.setHeader("Content-Type", "text/plain");
First the Content-Type header is set to text/plain. Then a plain text string is written to the
writer obtained from the response object.
Content-Length
The Content-Length header tells the browser how many bytes your servlet is sending back. If
you are sending binary data back you need to set the content length header. Here is how:
response.setHeader("Content-Length", "31642");
Again, you will first have to set the Content-Type header to the type matching the data you are
sending back. For instance, the content type for a PNG image is image/png.
You can search for "mime types" in your favourite search engine to find a list of mime types
(content types), so you can find the mime type for the content you are sending back.
In order to write binary data back to the browser you cannot use the Writer obtained from
response.getWriter(). Afterall, Writer's are intended for text.
Instead you have to use the OutputStream obtained from the response.getOutputStream()
method. Here is how:
outputStream.write(...);
response.sendRedirect("http://jenkov.com");
RequestDispatcher
The RequestDispatcher class enables your servlet to "call" another servlet from inside another
servlet. The other servlet is called as if an HTTP request was sent to it by a browser.
You can obtain a RequestDispatcher from the HttpServletRequest object, like this:
RequestDispatcher requestDispatcher =
request.getRequestDispatcher("/anotherURL.simple");
}
The above code obtains a RequestDispatcher targeted at whatever Servlet (or JSP) that is
mapped to the URL /anotherUrl.simple.
You can call the RequestDispatcher using either its include() or forward() method:
requestDispatcher.forward(request, response);
requestDispatcher.include(request, response);
By calling either the include() or forward() method the servlet container activates whatever
Servlet is mapped to the URL the RequestDispatcher.
The activated servlet has access to the same request as the servlet calling it, and will write to the
same response as your current servlet. That way you can merge the output of servlets into a
single repsonse.
There is a little difference between calling the forward() and include() method.
The forward() method intended for use in forwarding the request, meaning after the response
of the calling servlet has been committed. You cannot merge response output using this method.
The include() method merges the response written by the calling servlet, and the activated
servlet. This way you can achieve "server side includes" using the include().
HttpSession
The HttpSession object represents a user session. A user session contains information about the
user across multiple HTTP requests.
When a user enters your site for the first time, the user is given a unique ID to identify his
session by. This ID is typically stored in a cookie or in a request parameter.
You can store values in the session object, and retrieve them later. First, let's see how you can
store values in the session object:
session.setAttribute("userName", "theUserName");
This code sets an attribute named "userName", with the value "theUserName".
Values stored in the session object are stored in the memory of the servlet container.
ServletContext
The ServletContext is an object that contains meta informaton about your web application.
You can access it via the HttpRequest object, like this:
Context Attributes
Just like in the session object you can store attributes in the servlet context. Here is how:
context.setAttribute("someValue", "aValue");
The attributes stored in the ServletContext are available to all servlets in your application, and
between requests and sessions. That means, that the attributes are available to all visitors of the
web application. Session attributes are just available to a single user.
The ServletContext attributes are still stored in the memory of the servlet container. That
means that the same problems exists as does with the session attributes, in server clusters.
Web.xml Servlet Configuration
For a Java servlet to be accessible from a browser, you must tell the servlet container what
servlets to deploy, and what URL's to map the servlets to. This is done in the web.xml file of
your Java web application.
If you are not familiar with the directory layout and contents of a Java web application,: Java
Web Application Directory Layout
Here is a list of the topics covered in this text about the web.xml servlet configuration:
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>controlServlet</servlet-name>
<servlet-class>com.jenkov.butterfly.ControlServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>controlServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
First you configure the servlet. This is done using the <servlet> element. Here you give the
servlet a name, and writes the class name of the servlet.
Second, you map the servlet to a URL or URL pattern. This is done in the <servlet-mapping>
element. In the above example, all URL's ending in .html are sent to the servlet.
/myServlet.do
/myServlet*
The * is a wild card, meaning any text. As you can see, you can either map a servlet to a single,
specific URL, or to a pattern of URL's, using a wild card (*). What you will use depends on what
the servlet does.
<servlet>
<servlet-name>controlServlet</servlet-name>
<servlet-class>com.jenkov.butterfly.ControlServlet</servlet-class>
<init-param>
<param-name>myParam</param-name>
<param-value>paramValue</param-value>
</init-param>
</servlet>
Here is how you read the init parameters from inside your servlet - in the servlets init()
method:
response.getWriter().write("<html><body>myParam = " +
this.myParam + "</body></html>");
}
}
A servlets init() method is called when the servlet container loads the servlet for the first time.
No one can access the servlet until the servlet has been loaded, and the init() method has been
called successfully.
Servlet Load-on-Startup
The <servlet> element has a subelement called <load-on-startup> which you can use to
control when the servlet container should load the servlet. If you do not specify a <load-on-
startup> element, the servlet container will typically load your servlet when the first request
arrives for it.
By setting a <load-on-startup> element, you can tell the servlet container to load the servlet as
soon as the servlet container starts. Remember, the servlets init() method is called when the
servlet is loaded.
<servlet>
<servlet-name>controlServlet</servlet-name>
<servlet-class>com.jenkov.webui.ControlServlet</servlet-class>
<init-param><param-name>container.script.static</param-name>
<param-value>/WEB-INF/container.script</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Context Parameters
You can also set some context parameters which can be read from all servlets in your
application. Here is how you configure a context parameter:
<context-param>
<param-name>myParam</param-name>
<param-value>the value</param-value>
</context-param>
Here is how you access the parameter from inside an HttpServlet subclass:
String myContextParam =
request.getSession()
.getServletContext()
.getInitParameter("myParam");
The WEB-INF Directory
The WEB-INF directory is located just below the web app root directory. This directory is A Meta
Information Directory. Files stored in here are not supposed to be accessible from a browser
(although your web app can access them internally, in your code).
Inside the WEB-INF directory there are two important directories (classes and lib, and one
important file (web.xml). These are described below.
web.xml
The web.xml file contains information about the web application, which is used by the Java web
server / servlet container in order to properly deploy and execute the web application. For
instance, the web.xml contains information about which servlets a web application should
deploy, and what URL's they should be mapped to. I will not get into more detail about the
web.xml file here. Just know, that it exists.
classes
The classes directory contains all compiled Java classes that are part of your web application.
The classes should be located in a directory structure matching their package structure, just like
if you were to run them directly from the commandline, or package them in a JAR file.
lib
The lib directory contains all JAR files used by your web application. This directory most often
contains any third party libraries that your application is using. You could, however, also put
your own classes into a JAR file, and locate it here, rather than putting those classes in the
classes directory.
HTTP Cookies are little pieces of data that a web application can store on the client machine of
users visiting the web application. Typically up to 4 kilo bytes of data. This text will explain how
to set, read and remove cookies from inside Java servlets (or JSPs).
Table of contents:
response.addCookie(cookie);
As you can see, the cookie is identified by a name, "myCookie", and has a value,
"myCookieValue". Thus, you can add many different cookies with different identifies (names).
It's a bit like a Hashtable.
Whenever the the browser accesses the web application it submits the cookies stored on the
client machine to the web application. Only cookies stored by the accessed web application are
submitted. Cookies from other web applications are not submitted.
Now you can iterate through the array of cookies and find the cookies you need. Unfortunately
there is no way to obtain a cookie with a specific name. The only way to find that cookie again is
to iterate the Cookie[] array and check each cookie name. Here is an example:
This example finds the cookie with the name "uid" and stores its value in the
If you need to access more than one cookie, you could iterate the Cookie[] array once, and put
the Cookie instances into a Map, using the cookie name as key, and the Cookie instance as value.
Here is how that could look:
After this code is executed, you can now access the cookies in the cookieMap using the cookie
names as keys (cookieMap.get("cookieName")).
Cookie Expiration
One important Cookie setting is the cookie expiration time. This time tells the browser receiving
the cookie how long time it should keep the cookie before deleting it.
You set the cookie expiration time via the setMaxAge() method. This method takes the number
of seconds the cookie is to live as parameter. Here is an example:
response.addCookie(cookie);
This example first creates a Cookie instance with the name "uid" and the value "123". Second, it
sets the expiration to 24 hours using the setMaxAge() method. 24 hours is 60 seconds x 60
minutes x 24 hours (24 x 60 x 60). Finally the example sets the cookie on the
HttpServletResponse object, so the cookie is included in the response sent to the browser.
Removing Cookies
Sometimes you may want to remove a cookie from the browser. You do so by setting the cookie
expiration time. You can set the expiration time to 0 or -1. If you set the expiration time to 0 the
cookie will be removed immediately from the browser. If you set the expiration time to -1 the
cookie will be deleted when the browser shuts down.
Here is an example:
cookie.setMaxAge(0);
response.addCookie(cookie);
If the browser already has a cookie stored with the name "uid", it will be deleted after receiving
the cookie with the same name ("uid") with an expiration time of 0. If the browser did not
already have the cookie stored, this new cookie is just thrown out immediately since its
expiration time is 0.