Servlet
●
Java programming language class used to extend the
capabilities of servers that host applications accessed via a
request-response programming model
●
Java class that implements the Servlet interface and
accepts requests that can come from Java classes, Web
clients, or other Servlets and generates responses
Servlet
●
To start making servlets, you'll need to have knowledge
about:
–
Java programming
–
Client-server concepts
–
Basic HTML and HTTP
●
To create a Servlet, you'll need to import in your java
program the standard extension classes in the packages
javax.servlet and javax.servlet.http.
–
javax.servlet contains the basic servlet framework
Servlet Architecture
Overview
●
Common Gateway Interface (CGI)
–
One of the most common ways of adding functionality for a web
server, prior to Servlets
–
Provides the server an interface to an external program, allowing it
to be called by the server to handle client requests
–
Designed in such a way that each call for a CGI resource creates a
new process on the server
● This approach imposed a heavy requirement on system resources, limiting the
Servlet Architecture
Overview
●
Servlets are designed to be able to bypass the CGI problem
and provide developers a robust Java solution to creating
applications for the Web.
●
With servlets, there is only one process that handles ALL
requests: the process required by the servlet container to
run.
●
Servlets are also loaded into memory only once: either the
container loads them into memory on server startup, or the
first time the servlet is required to service a client.
import java.io.*;
import javax.servlet.*; import javax.servlet.http.*;
public class HelloServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//"request" is used for reading incoming HTTP headers
// HTML form data (e.g. data the user entered and submitted) // and other data that can be inferred from the client request.
// "response" is for specifying the HTTP response line and // headers(e.g. specifying the content type, setting cookies). // It also contains methods that allow the servlet to generate // responses for the client.
PrintWriter out = response.getWriter();
out.println("<HTML> <TITLE>Hello Page</TITLE><BODY><br>"); out.println("<h1>Hello World!</h1>");
out.println("</BODY></HTML>"); //"out" for sending content to browser
Servlet First Look
●
HelloServlet shows the structure of a basic servlet that
handles GET requests, as well as displaying the traditional
'Hello World'.
●
The first part is simply importing classes:
import java.io.*;
–
java.io (for PrintWriter, etc.)
import javax.servlet.*;
import javax.servlet.http.*;
–
javax.servlet and javax.servlet.http are packages that provide
interfaces and classes for wrtiting servlets (for HttpServlet,
HttpServletRequest and HttpServletResponse).
Servlet First Look
●
By extending HttpServlet, this class inherits methods that
are automatically called by the server depending on certain
conditions.
public class HelloServlet extends HttpServlet {
–
doGet method is inherited and overriden
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
● HttpServletRequest object: provides access to all information regarding the
client's request (HTTP request headers, the HTTP request method that they used, etc.).
Servlet First Look
●
Aside from the comments, there are only several lines that
we use to display "Hello World!"
PrintWriter out = response.getWriter();out.println("<HTML> <TITLE>Hello Page</TITLE><BODY><br>"); out.println("<h1>Hello World!</h1>");
out.println("</BODY></HTML>");
Servlet First Look
Testing HelloServlet
●
At this point we need to be able to display the output of
HelloServlet.
●
To initially abstract the details of servlet deployment and
configuration, we will be making use of the automated tools
provided by IDEs
●
Sun Studio Enterprise 8
–
The IDE we will use.
–
Available for free for members of the Sun Developer Network.
–
Has complete support for the servlet and JSP specifications, as well
Testing HelloServlet
●
First, we need to create a new web application project:
–
To do this select New->Project in the menubar.
–
In the screen that appears next, select the Web category.
–
On the right, choose New Web Application.
●
The next screen will prompt you for details about the project:
–
For HelloServlet, our first test servlet, let's make use of
"FirstServletProject" as our project name, and make use of default
values for the other fields.
Testing HelloServlet
●
To add our servlet to the application:
–
Right click on Source Packages, select New->Servlet.
–
If Servlet does not appear in the New context menu, select
New->File/Folder instead. In the next screen, select the Web category,
then Servlet.
Testing HelloServlet
●
The IDE will then launch a series of screens which will ask
for details about the servlet to be created.
–
In the first screen, name the servlet FirstServlet. Under package
name, use jedi.servlet. (see next slide)
–
In the screen that follows, leave the default values untouched. Then,
Testing HelloServlet
●
The IDE has created and partially implemented for us a
method named processRequest.
–
ProcessRequest
● Simply a method that will be called by both doGet and doPost. ● Its content forms the basis of the functionality of our servlet.
–
First, remove all contents of the processRequest method. Then,
copy / paste the contents of the doGet method from the code listing
for the test servlet into it. (see next slide)
●
To run, press Shift + F6. The IDE will then package, deploy,
and invoke the servlet automatically for us, producing the
output.
Servlet Lifecycle
●
A servlet is managed through a well-defined lifecycle
described in the servlet specification.
●
The servlet lifecycle describes how a servlet is loaded,
instantiated, initialized, services requests, destroyed and
finally garbage collected
●
The life cycle of a servlet is controlled by the container in
Servlet Lifecycle
●
The servlet life cycle allows servlet engines to address both
the performance and resource problems of CGI and the
security concerns of low-level server API programming.
–
A servlet engine may execute all its servlets in a single Java virtual
machine (JVM):
● Because they are in the same JVM, servlets can efficiently share data with each
other, yet they are prevented by the Java language from accessing one another's private data.
● Servlets may also be allowed to persist between requests as object instances,
Servlet Lifecycle
●
The major events in a servlet's life:
–
Instantiation
–
Initialization
–
Service
–
Destruction
Servlet Lifecycle
●
Instantiation
–
The servlet class is loaded into memory, and an instance is created
by the servlet container.
–
By default, a servlet container practices what is called lazy loading.
● A servlet class is loaded into memory, instantiated, and initialized only after a
request has been made for it.
● Advantage: makes for a faster startup time for the application.
● Disadvantage: there is a little bit of overhead associated for the first call to each
servlet.
–
A servlet goes through the instantiation phase only once per lifetime.
–
The relevant method that the container will call at this stage will be
Servlet Lifecycle
●
Initialization
–
The servlet is primed for use in the application.
–
A servlet also goes through this stage only once.
–
It is only after this phase that our object instance starts to be called a
servlet.
–
The method that is called by the container at this point is the init()
method.
public void init(ServletConfig config)
● ServletConfig object: contains the servlet's configuration information, as well as
provides a way for the servlet to access application-wide information and facilities.
Servlet Lifecycle
(Initialization continued)
–
After initialization, the servlet is ready to handle client requests.
–
This method can only be called again when the server reloads the
servlet . The server cannot reload a servlet until after the server has
destroyed the servlet by calling the destroy method.
Servlet Lifecycle
●
Service
–
The phase that a servlet is in for the bulk of its lifetime.
–
The servlet can be repeatedly called by the container to provide its
functionality.
–
The method invoked by the servlet container during this phase is
the service() method.
public void service(ServletRequest req, ServletResponse res)
● ServletRequest and ServletResponse objects: provides methods to extract
information from the user's request and methods to generate the response.
● One important thing to note is that the servlet container makes these repeated
calls to the service method using separate threads. That is, mostly there is only one active servlet instance taking up space in memory, handling multiple
Servlet Lifecycle
(Service continued)
–
For HTTP-specific servlets (servlets extending HttpServlet),
developers should not override the service method directly. Instead,
developers should override any of the following methods:
public void doGet(HttpServletRequest req, HttpServletResponse res) public void doPost(HttpServletRequest req, HttpServletResponse res) public void doPut(HttpServletRequest req, HttpServletResponse res) public void doTrace(HttpServletRequest req, HttpServletResponse res)
● Each of these methods correspond to a specific HTTP method (GET, POST, ...). ● Since most HTTP calls that developers concern themselves with are either GET
Servlet Lifecycle
●
Destruction
–
When a servlet is to be removed from a container's management, it
is said to be in its destruction phase.
● There are times when a servlet container will run out of memory, or detect that
the amount of free memory it has is within a certain threshold. When this
happens, the container will attempt to free up memory by destroying one or more servlet instances. What servlet is removed is determined by the servlet container and is not something a developer has direct control over.
● A container will also free up a servlet instance as part of its shutdown process.
–
The method called by the container before this is accomplished is
the destroy() method.
● Servlet should be coded to explicitly free up resources that it handles, such as
Servlet Lifecycle
●
Garbage Collection
–
This phase in the servlet lifecycle is equivalent to that in any other
Java object.
–
Occurs just before an object instance is removed from memory.
–
Developers have no direct control as to when this will occur.
Review
●
The main purpose of a servlet is to provide dynamic content
to the user.
●
By definition, dynamic content is content that changes in
response to various conditions. Examples of which are the
particulars of a user request, time of day, etc.
Handling Requests and
Responses
●
To give the servlet access to the particulars of a user's
request, it is provided an instance of a ServletRequest
object that encapsulates those details.
●
HTTP-based servlets are given a subclass called
HTTPServletRequest, that provides additional methods for
retrieving HTTP-specific info, such as cookie information,
header details, etc.
Handling Requests and
Responses
●
Form Data and Parameters
●
Retrieving Info from the Request URL
●
Header Information
Form Data and Parameters
●
request.getParameter
●
request.getParameterValues
request.getParameter
●
One of the most often encountered scenarios requiring
dynamic content is when we want our application to respond
to user data as presented in a form.
<HTML>
<TITLE>Halloa!</TITLE> <BODY>
<form action="GetParameterServlet" method="post">
Enter user name: <input type="text" name="userName"/> </br> <input type="submit" value="Greet me!"/>
</form> </BODY> </HTML>
request.getParameter
●
For this and other similar scenarios, Java provides the
getParameter method in the HttpServletRequest object.
public String getParameter(String parameterName)–
This method takes in the name of the parameter we wish to retrieve
and returns the String value of that parameter.
●
Now, let's create the code that takes in the user's name and
outputs a simple greeting, and the HTML used to display the
form.
public class GetParameterServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// retrieve the value supplied by the user
String userName = request.getParameter("userName");
// retrieve the PrintWriter object and use it to output the greeting
PrintWriter out = response.getWriter(); out.println("<HTML><BODY><H1>");
out.println("HELLO AND WELCOME, " + userName + "!"); out.println("</H1></BODY></HTML>");
out.close(); }
request.getParameter
●
If we were to supply "JEDI" as the value for the form we
<html>
<title>Choice selection</title><body>
<H1>What sports activities do you perform?</h1>
<form action="GetParameterValuesServlet" method="post">
<input type="checkbox" name="sports" value="Biking"> Biking <br/>
<input type="checkbox" name="sports" value="Table Tennis"> Table Tennis <br/> <input type="checkbox" name="sports" value="Swimming"> Swimming <br/>
<input type="checkbox" name="sports" value="Basketball"> Basketball <br/> <input type="checkbox" name="sports" value="Others"> Others <br/>
<input type="submit"> </form></body>
request.getParameterValues
●
There are times when we need to retrieve data from a form
with multiple elements of the same name. In this case, using
the getParameter method will return only the value of the
first element with the given name. To retrieve all of the
values, we use the getParameterValues method:
public String[] getParameterValues(String parameterName)
–
Also takes in the name of the parameter whose values we wish to
retrieve.
–
Returns a String array.
public class GetParameterValuesServlet extends HttpServlet { public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletExceptionm IOException{ String paramValues[] = request.getParameterValues("sports");
StringBuffer myResponse = new StringBuffer(); PrintWriter out = response.getWriter();
out.println("<HTML><TITLE>Your choices</TITLE>"); out.println("<BODY><H1>Your choices were : </H1>"); for (int i = 0; i < paramValues.length; i++) {
out.println("<br/><li>"); out.println(paramValues[i]); }
request.getParameterValues
●
If the entries "Biking", "Table Tennis", and "Swimming" are
request.getParameterNames
●
There are times when we want our servlet to be aware of
the name of one or more of the parameters within the form
without having to hardcode them into the servlet. In this
case, we can use the getParameterNames method:
public Enumeration getParameterNames()–
The Enumeration object that this method returns contains all of the
Retrieving Info from the
Request URL
●
A request URL is composed of the following parts:
http://[host]:[port]/[requestPath]?[queryString]
●
To retrieve the curent values for each part from the user's
request, call on methods in the HttpServletRequest object:
–
Host – request.getServerName()
–
Port – request.getServerPort()
–
Request Path – divided into 2 logical components in Java:
● Context – the context of the web application. Can be retrieved by invoking
Retrieving Info from the
Request URL
●
So, with a request URL of:
http://www.myjedi.net:8080/HelloApp/greetUser?name=Jedi
●
The following table presents the results yielded if we call on
the aforementioned methods:
request.getServerName() www.myjedi.net request.getServerPort() 8888
request.getContextPath() HelloApp request.getPathInfo() greetUser request.getQueryString() name=Jedi
Header Information
●
Can be retrieved from within the servlet by calling on the
following methods in HttpServletRequest:
–
getHeader(String name)
● Returns the value of the specified header as a String; null, if it does not exist.
–
getHeaders(String name)
● Returns all values for the specified header as an Enumeration object.
–
getHeaderNames()
● Returns as an Enumeration object the names of all headers included in the HTTP
request.
–
getIntHeader(String name)
Header Information
(Methods in HttpServletRequest continued)
–
getDateHeader(String name)
● Returns the value of the specified header as a long value that represents a Date
object; -1, if it does not exist.
● Throws an IllegalArgumentException if the header cannot be converted to a
Output Generation
●
In all the previous examples, we are able to generate
dynamic output for the user by using methods exposed in
the HttpServletResponse object.
–
So far, we have been making use mostly of the getWriter method.
● getWriter returns a PrintWriter object associated with our response to the user.
import java.io.*;
import javax.servlet.*; import javax.servlet.http.*;
public class HelloServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//"request" is used for reading incoming HTTP headers
// HTML form data (e.g. data the user entered and submitted) // and other data that can be inferred from the client request.
// "response" is for specifying the HTTP response line and // headers(e.g. specifying the content type, setting cookies). // It also contains methods that allow the servlet to generate // responses for the client.
PrintWriter out = response.getWriter();
out.println("<HTML> <TITLE>Hello Page</TITLE><BODY><br>"); out.println("<h1>Hello World!</h1>");
out.println("</BODY></HTML>"); //"out" for sending content to browser
Output Generation
●
Other notable methods in the HttpServletResponse object
are:
–
SetContentType
● Informs the client's browser of the MIME type of the output it is about to receive. ● Limited to text outputs: JPEG, PDF, DOC, XLS, etc.
–
getOutputStream
● Retrieves an instance of the OutputStream object associated with our response
to the user.
● Using this OutputStream, we can then use standard Java I/O objects and
public JPEGOutputServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
// define a byte array to hold data
byte bufferArray[] = new byte[1024];
// retrieve the ServletContext which we will use to retrieve the resource
ServletContext ctxt = getServletContext();
// inform the browser that the resource we are sending is a GIF file
response.setContentType("image/gif");
// retrieve the output stream we will use to produce response
ServletOutputStream os = response.getOutputStream();
// retrieve the resource as an input stream
InputStream is = ctxt.getResource("/WEB-INF/images/logo.gif").openStream();
// read the contents of the resource and write it afterwards into the outputstream
int read = is.read(bufferArray); while (read != -1) {
os.write(bufferArray);
read = is.read(bufferArray); }
// close the streams used
Configuration, Packaging,
and Deployment
●
In all the examples we have done so far, we have used the
tools inherent in the Enterprise IDE to abstract the details of
web application configuration, packaging, and deployment.
We will take a look at those details now.
Web Application
Configuration
●
The servlet specification defines an XML file named web.xml
that acts as a configuration file for our web applications. This
file is also called the deployment descriptor.
●
We will use our FirstServlet example as our starting point in
exploring web.xml.
–
NOTE: The web.xml for Enterprise web application projects can be
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>FirstServlet</servlet-name> <servlet-class>jedi.servlet.FirstServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>FirstServlet</servlet-name> <url-pattern>/FirstServlet</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file> index.jsp </welcome-file> </welcome-file-list>
web.xml
●
<web-app>
–
Serves as both the root element of the configuration file as well as
declaring the necessary info for the servlet container to recognize
the file as a valid deployment descriptor file.
●
<servlet>
–
Each instance defines a servlet to be used by the application.
–
Child nodes:
● <servlet-name> – A logical name supplied by the developer which will be used
for all future references to this servlet.
● <servlet-class> – The fully qualified class name of the servlet.
web.xml
●
<servlet-mapping>
–
Each instance defines a mapping to a servlet.
–
Child nodes:
● <servlet-name> – the logical name of the servlet to be mapped. Must be defined
previously in the descriptor file.
● <url-pattern> – the URL pattern to which this servlet will be mapped. Having a
value of /* will make all requests to your application redirected to your servlet.
–
Take note that all servlet definitions must first be supplied before
web.xml
●
<session-config>
–
Defines configuration details for session management.
●
<welcome-file-list>
–
Defines a web component that will be automatically loaded if the
user enters a request for the application without specifying a
particular resource.
–
More than one file can be specified but the first one visible to the
Packaging the Web
Application
●
Our application can be deployed to a server by making use
of what is called a WAR file.
–
WAR files are the same as JARs: they contain Java application code
compressed using the ZIP format.
–
Informally, WAR stands for Web Archive.
Contains HTML, images, other static content, plus JSPs Contains meta-information about your application (optional)
All contents of this folder cannot be seen from the web browser
Contains class files of Java classes created for this application (optional) Contains JAR files of any third-party libraries used by your app (optional)
Generating WAR Files
●
To produce the WAR file containing our web application
from an existing project in Sun Studio Enterprise 8:
–
Right click on the project name in the Project view, and select Build
Generating WAR Files
(WAR file... continued)
–
The IDE will inform you if the build operation is successful. It will
Packaging the Web
Application
●
Using an Ant build file to package the application
–
Aside from using an IDE to package the web application, we can
also make use of a build tool that can automate for us the
compilation and packaging process.
–
Ant
● A build tool that has wide industry acceptance.
● An open-source project of the Apache Software Foundation, and can be
downloaded from: http://ant.apache.org
● Reads in a build file (traditionally named build.xml) made up of targets, which
essentially define logical activities that can be carried out by the build file. These targets are composed of one or more tasks that define the details of how the targets perform their activities.
Requirements of the Build File
●
It must be located in the project root of the directory
structure recommended by the Apache Software Foundation
for web application development.
●
Additionally, there must also exist a lib directory in the
project root that will contain all JAR dependencies of the
application.
–
There must exist a file named build.properties in the same directory
as the build script and must contain values for the following
properties:
● app.name – the name of the application / project.
● appserver.home – the installation directory of a Sun Application Server 8.1
Using an Ant Build File
●
The following is the directory structure recommended for
web application development:
–
This directory structure was designed to be separate from the
After build script has executed, will contain the application in a directory structure recognized by servlet containers.
After build script has executed, will contain the WAR file.
Used to contain whatever documentation is used by the dev team. Directory under which all Java source files must be placed.
Directory containing all static content of the app (HTML, JSP), will be the basis of the document root of your project.
Directory containing configuration files such as the deployment descriptor (web.xml), tag library descriptors, etc.
Using an Ant Build File
(Directory Structure continued)
–
Apache lists the following advantages for having such a separate
directory structure:
● Contents of source directory are more easily administered, moved, or backed up
if the deployment version is not intermixed.
● Source code control is easier to manage on directories that contain only source
files (no compiled classes, etc.).
● The files that make up an installable distribution of the application are easier to
Using an Ant Build File
(Directory Structure continued)
–
To perform the packaging of an app using this structure, run the
following on the command-line (in the same directory containing the
build file):
ant dist
● This will call the dist target in the build file which will generate the WAR file and
place it into the dist directory. This WAR file can then be loaded into the target servlet container using the admin tools provided by the container.
Deployment into Server
●
Servlet containers generally contain administrative tools that
can be used to deploy web applications.
●
Steps required to deploy the generated WAR file into Sun
Application Server 8.1:
–
First step, log-in into the administrative console. This can be
accessed by entering the following URL in your browser:
http://localhost:[ADMIN_PORT]
● ADMIN_PORT is the port configured during installation to handle administrative
Deployment into Server
(Steps continued)
–
Second, left click on the Web Applications tab on the panel to the
Deployment into Server
(Steps continued)
–
In the screen that appears next, click on the Browse button to select
the WAR file to upload. Click on the Next button found in the upper
right.
–
Click on the Finish button in the next screen.
Servlet and Application
Parameters
●
ServletConfig and Servlet Initialization Parameters
ServletConfig and Servlet
Initialization Parameters
●
ServletConfig object
–
Passed to a specific servlet during its initialization phase.
–
Using this, a servlet can:
● Retrieve information specific to itself, such as initialization parameters. ● Gain access to an instance of the ServletContext object.
●
Initialization parameters are of great use:
–
When dealing with information that may vary with each deployment
of the application.
–
Allows deployers the ability to change servlet behaviour without
ServletConfig and Servlet
Initialization Parameters
●
We can add initialization parameters to the servlet by
specifying them in the servlet's definition in the deployment
descriptor.
... <servlet> <servlet-name>FirstServlet</servlet-name> <servlet-class>jedi.servlet.FirstServlet</servlet-class> <init-param> <param-name>debugEnabled</param-name>ServletConfig and Servlet
Initialization Parameters
(Adding Initialization Parameters continued)
–
The <init-param> and </init-param> tags tell the container that we
are starting and ending parameter definition, respectively:
● <param-name> defines the name of the parameterServletConfig and Servlet
Initialization Parameters
●
To gain access to the servlet parameters, a servlet must first
get a handle on its ServletConfig object, which can be done
by calling on the getServletConfig() method. Afterwards, the
parameter value can be retrieved as a String by calling the
getInitParameter method and supplying the value of
<param-name> as the parameter.
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletConfig config = getServletConfig();
ServletContext and
Application Parameters
●
The ServletContext object gives the servlet access to the
application context.
–
Application context
● Area which an application moves in.
● Provided by the container for each web application with each application's
context being separate from each other – an application may not access the context of another app.
–
Having access to this context is important:
● Servlet can retrieve application-wide parameters and data.
● Servlet can also store data that can be retrieved by any components in the
ServletContext and
Application Parameters
●
In much the same way that initialization parameters can be
supplied for individual servlets, they can also be supplied for
use by the entire application.
●
Example of how to add application-wide parameters:
<context-param>
<param-name>databaseURL</param-name>
<param-value>jdbc:postgresql://localhost:5432/jedidb</param-value> </context-param>
ServletContext and
Application Parameters
(Adding Application-wide Parameters continued)
–
Each instance of <context-param> defines a parameter for use by
the whole application.
● <param-name> and <param-value> works the same way as their <init-param>
counterparts
–
NOTE: Again, be reminded that the specification is strict about the
ordering of elements inside the deployment descriptor. To keep your
web.xml valid, all <context-param> entries must be located BEFORE
any <servlet> entries.
ServletContext and
Application Parameters
●
Retrieving the parameter values is very similar to that used
for retrieving servlet-specific parameters. Only this time, it is
an instance of ServletContext that the servlet must have a
handle to. This can be retrieved by calling the
getServletContext() method from an instance of the servlet's
ServletConfig object.
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext ctxt = getServletConfig().getServletContext(); String jdbcURL = ctxt.getInitParameter("databaseURL");