Servlet
Why Servlet ?
Dynamic web applications requires processing of request information, accessing other resources and generating response content dynamically. CGI (Common Gateway Interface) technology was being used to generate dynamic contents.
CGI Technology
CGI technology was being used to provide dynamic content to the user. It executes a program that resides in the server. It can access databases to produce relevant dynamic content. Program written in server can be written in native OS language such as C++. CGI can be implemented using any programming language but mostly CGI is implemented in Perl.
Drawbacks of CGI Technology
- For each request CGI server receives, new OS process is created
- As number of requests increases, response time also increases
- Program executed by CGI scripts are written in native language (C, C++ or Perl), so it is platform dependent
Need of better web technology like servlet
A better web technology was required to overcome the drawbacks of CGI technology. A technology that provide lightweight, robust and portable. Servlet, being developed on Java Technologies, provides all the capabilities of Java and brings ultimate solution to develop dynamic web applications.
Servlet is not limited to only web technology, it can be used by any request-response programming model.
Servlet vs CGI
What is Servlet ?
- Servlet is Web technology which is used to develop server side web components for dynamic web applications.
- Java Servlet technology provides dynamic, user-oriented content in web applications using a request-response programming model.
- A servlet is a Java programming language class used to extend the capabilities of servers that host applications accessed by means of a request-response programming model.
- Although Servlets can respond to any type of request, they are commonly used to extend the applications hosted by web servers.
- For such applications, Java Servlet technology defines HTTP-specific servlet classes.
- The javax.servlet and javax.servlet.http packages provide interfaces and classes for writing servlets.
- All servlets must implement the Servlet interface, which defines lifecycle methods.
- When implementing a generic service, you can use or extend the GenericServlet class provided with the Java Servlet API.
- The HttpServlet class provides methods, such as doGet and doPost, for handling HTTP-specific services
What it does?
- Receives different type of requests(like GET, POST)
- Process the request data
- Prepares HTML response
Web Server => Web Container => Web applications => Web Components
Servlet API
Servlet Lifecycle
The lifecycle of a Servlet is controlled by the container in which the Servlet has been deployed. All request reached to the container and mapped to Servlet using URL pattern. Once mapping Servlet found, web container performs the following steps:
Step 1
If instance of the servlet does not exists, then web container
- Loads the Servlet class
- Creates instance of the loaded servlet class by calling
new()
method - Initializes the servlet instance by calling the
init()
method
Step 2
Container invoked service method(doGet()
, doPost()
, service()
etc), passing request
and response
objects
Step 3
If it needs to remove the servlet, container finalizes()
the servlet by calling Servlet’s destroy()
method
Creating and Initializing a Servlet
- Use @WebServlet annotations to define a servlet component in web application
- It’s a class level annotation and contains metadata about the servlet being declared
- Annotated servlet must declare at least one URL pattern (urlPattern=”pattern” or value=”pattern”)
- Other attributes are optional with default setting
- Class annotated with @WebServlet must extend javax.servlet.http.HttpServlet class
- Example:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
@WebServlet("/report")
public class MoodServlet extends HttpServlet {
…
}
Note:
- Web container Loads -> Instantiate -> Initializes the servlet and then Delivers requests to it from Clients
- This process can be customized by
- Allowing servlet to read configuration data
- Initialize resources and
- Perform any one time activities
- This can be done by
- Either overriding init methos of Servler interface
- Or specifying the initParam attribute of the @WebServlet annotation
- intiParam attribute contains @WebInitParam annotation
- If it cannot completes its initialization process, servlet throws an UnavailableException
- Use initialization parameter to provide data needed by a particular servlet
- In contrast, a context parameter provide data that is available to all components of the Web Application
Writing Service Methods
Service method is any method in servlet class that provides a service to client. Examples of service methods are service
method of GenericServlet
and doGet
, doPost
, doPut
etc methods of HttpServlet
. Any other protocol-specific methods defined by a class that implements Servlet
The general pattern of service method is to
- Extract information from servlet
- Access external resources
- Populate the response based in request information, For HTTP servlets, the correct way for populating the response is to do the following
- Retrieve an output stream from the response e.g.
PrintWriter pw = response.getWriter();
- Fill in the response headers
- Write any body content to the output stream
- Retrieve an output stream from the response e.g.
Note:
Response headers must always be set before the response has been committed. The Web container will ignore any attempt to set or add headers after the response has been committed.
Getting information from Requests
A request contains data passed between client and the servlet. All requests implements ServletRequest
interface. ServletRequest
interface defines methods for accessing the following information.
- Parameters(used to convey information between clients and servlets)
- Object-valued attributed, typically used to pass information between
- Web Container and a servlet
- Collaborating servlets (i.e. one servlet to another)
- Information about Protocol used to communicate the request
- Information about Client and server involved in the request
- Information relevant to localization
- This data can also be retrived as input stream but needs to be parsed manually
- To read character data, use BufferedReader objects by request’s getReader
- To read binary data, use ServletInputStream object by getInputStream
- HTTP servlets are passed an HTTP request object, HttPServletRequest
- It contains request URL, HTTP header, query-string and so on
- An HTTP request URL contains following parts
- http://[host]:[port][request-path]?[query-string]
- The request path is futher composed of following elements
- Context path
- Servlet path
- Path info
- You can use the getContextPath, getServletPath, and getPathInfo methods of the HttpServletRequest interface to access this information.
- Except for URL encoding differences between the request URI and the path parts, the request URI is always comprised of the context path plus the servlet path plus the path info.
- Query strings are composed of a set of parameters and values. Individual parameters are retrieved from a request by using the getParameter method. There are two ways to generate query strings.
- A query string can explicitly appear in a web page.
- A query string is appended to a URL when a form with a GET HTTP method is submitted.
Constructing Response
A response contains data passed between a server and client. All responses implements ServletResponse
interface. This interface defines methods that allows you to do the following
- Retrieve an output stream to use to send data to the client
- To send character data, use
PrintWriter
returned by response’sgetWriter
- To send binary data in a MIME body respose, use
ServletOutputStream
returned bygetOutputStream
- To mix binary and text data, user
ServletOutputStream
and manage the character section manually
- To send character data, use
- Indicate the content type (for example text/html)
- To do this
setContentType(String)
method is available - This method must be called before response is committed
- To do this
- Indicate whether to buffer output with the
setBufferSize(int)
method- By default, any content written to the output stream is immediately sent to the client
- Buffering allows content to be written before anything is sent back to the client, thus providing the servlet with more time to set appropriate status codes and headers or forward to another web resource. The method must be called before any content is written or before the response is committed.
- Set localization information such as locale and character encoding
- HTTP response objects,
javax.servlet.http.HttpServletResponse
, have fields representing HTTP headers, such as the following.- Status codes, which are used to indicate the reason a request is not satisfied or that a request has been redirected.
- Cookies, which are used to store application-specific information at the client. Sometimes, cookies are used to maintain an identifier for tracking a user's session
Parameters
- Parameters are used to pass data among different web components
- These are name-values pairs i.e. value can easily be accessed by using it’s corresponding name
- Once set, cannot be modified hence parameters are read-only
- Web container stores parameters in it’s corresponding objects
Types of parameter
There are mainly three type of parameters
ServletRequest
parametersServletConfig
parametersServletContext
parameters
1. ServletRequest parameters
- Web client sends data to Web server in request header or body as query string
- Web container collects this query string data from request header/body and stores in HttpServletRequest object as parameter(s)
- These parameters and associated values can be fetched using HttpServletRequest object
- There are mainly three ways to fetch values from these parameters
Using getParameter
and getParameterValues
String name = request.getParameter("name");
String jModules[] = request.getParameterValues("jModules");
Using getParameterMap
Map<String, String[]> map = request.getParameterMap();
Set paramNames = map.keySet();
Iterator it = paramNames.iterator();
while (it.hasNext()) {
String paramName = (String) it.next();
Object paramValue = map.get(paramName);
String[] paramValueArray = (String[]) paramValue;
for (int i = 0; i < paramValueArray.length; i++) {
out.println("<label>" + paramValueArray[i] + " </label>");
}
out.println("<br>");
}
Using getParameterNames
Enumeration<String> paramEnum = request.getParameterNames();
List<String> paramList = Collections.list(paramEnum);
for (String param : paramList) {
out.println(request.getParameter(param) + "<br>");
}
2. ServletConfig parameters
- ServletConfig is an interface in javax.servlet package
- Web container vendor provides implementing class for the same
- Each servlet has its own ServletConfig object, which is not sharable with other servlets
- Data that is common for all user but specific to particular servlet can store in ServletConfig
- This data can be specified in either web.xml or using @WebInitParam annotation
@WebServlet(urlPatterns = { "/EnrollmentJavaServlet" }, initParams = {
@WebInitParam(name = "trainerName", value = "Atul", description = "Name of Java trainer"),
@WebInitParam(name = "trainerEmailId", value = "contact@atuldwivedi.com", description = "Email ID of Java trainer") })
public class EnrollmentJavaServlet extends HttpServlet {
...
}
- Web container reads this data from web.xml/annotation and set in ServletConfig object
- ServletConfig object can be obtained either by getServletConfig of Overriding init method
ServletConfig cfg = getServletConfig();
or
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
super.init(config);
this.cfg = config;
this.ctx = config.getServletContext();
}
Fetch ServletConfig parameters using getInitParameter
//Get config parameter values
ServletConfig cfg = getServletConfig();
String trainerName = cfg.getInitParameter("trainerName");
String trainerEmailId = cfg.getInitParameter("trainerEmailId");
Fetch ServletConfig parameter using getInitParameterNames
Enumeration<String> paramEnum = request.getParameterNames();
List<String> paramList = Collections.list(paramEnum);
for (String param : paramList) {
out.print("<label>" + param + ": </label><b><label>"
+ request.getParameter(param) + "</label></b> <br>");
}
3. ServletContext parameters
- ServletContext is an interface in javax.servlet package
- Web container vendor provides implementing class for the same
- One Web application has only one ServletContext object i.e. one for all servlets
- Data is shared among all web components
- Data that is common among all users and across all servlet can be stored in ServletContext
- ServletContext object can be obtained from ServletConfig.getServletContext
- This data can be specified in web.xml
<context-param>
<param-name>institute</param-name>
<param-value>Info Campus</param-value>
</context-param>
Fetch ServletContext parameters using getInitParameter
//Get context parameter values
ServletContext ctx = cfg.getServletContext();
String instituteName = ctx.getInitParameter("institute");
Fetch ServletContext parameters using getInitParameterNames
ServletContext ctx = cfg.getServletContext();
Enumeration<String> ctxParamEnum = ctx.getInitParameterNames();
List<String> ctxParamList = Collections.list(ctxParamEnum);
for (String ctxParam : ctxParamList) {
out.print("<label>" + ctxParam + ": </label><b><label>"
+ ctx.getInitParameter(ctxParam) + "</label></b> <br>");
}
Request Dispatcher
- RequestDispatcher is and interface in javax.servlet package
- It is used to dispatch the request from one web component to other using forward() method
- It can also include other web component in Servlet like HTML, JSP using include() method
- RequestDispatcher object can be obtained using request.getRequestDispatche()
RequestDispatcher rd = request.getRequestDispatcher(path + page);
- RequestDispatcher has two methods
- public void forward(ServletRequest req, ServletResponse res)
- public void include(ServletRequest req, ServletResponse res)
The forward() method
- This method forward requests from
- Servlet to HMLT similarly JSP to HTML
- Servlet to JSP similarly JSP to JSP
- Servlet to Servlet similarly JSP to Servlet
- It is used to provide programmatically access to resources placed inside WEB-INF
- Once servlet can have multiple forward() placed in conditional blocked such that only one will be executed otherwise java.lang.IllegalStateException will be thrown
- After forwarding statement servlet can have following statements to execute but those statements cannot write any content to response stream
Syntax
RequestDispatcher rd = request.getRequestDispatcher(path + page);
rd.forward(request, response);
Example
A typical example of using RequestDispatcher.forward in login scenario where if login is successful, forward the request to home page otherwise forward it to error page. Below is the code snippet for the same:
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String userName = request.getParameter("userName");
String password = request.getParameter("password");
if (userName.equals(password)) {
page = "home.html";
} else {
page = "error.html";
}
RequestDispatcher rd = request.getRequestDispatcher(path + page);
rd.forward(request, response);
}
The include() method
- Used to include other resources like servlet and/or JSP in response
- Unlike forward(), servlet can have many include() statements and all will be executed
Syntax
RequestDispatcher rd1 = request.getRequestDispatcher(path+"header.html");
rd1.include(request, response);
Example
A typical example of using include() method is to include header and footer in the web page and may be menu section in the page.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String page = request.getParameter("page");
RequestDispatcher rd1 = request.getRequestDispatcher(path+"header.html");
rd1.include(request, response);
RequestDispatcher rd2 = request.getRequestDispatcher(path+page+".html");
rd2.include(request, response);
RequestDispatcher rd3 = request.getRequestDispatcher(path+"footer.html");
rd3.include(request, response);
}
Send Redirect
- Redirects the control to another web component
- This includes browser refresh or url change
Syntax
response.sendRedirect("index.html");
Example
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
String enteredURL = request.getParameter("url");
if (enteredURL == null || enteredURL.length() == 0) {
RequestDispatcher rd = request.getRequestDispatcher("error.html");
rd.forward(request, response);
} else {
response.sendRedirect("index.html");
}
}
RequestDispatcher.forward v/s HttpServletResponse.sendRedirect
Filters
Why
In the processing of requests by Servlets there may be some tasks that need to be done before and after request processing. These tasks are not intended to be done by Servlets, but are essentials in order to serve the requests.
Tasks need to be done before request processing called request pre-processing. These task also includes cross cutting concerns like security and logging. Eg:
- Security
- Logging
- Authentication and Authorization
- Session validity
Tasks need to be done after request processing called request post-processing. Eg:
- Data compression
- Data encryption or encoding
- URL rewriting
These tasks can be done in servlet itself but writing code for same task in different servlets may incur maintenance cost. These type of common tasks can be separated from servlet and can be used before servlet start processing request as well as after servlet completes processing of request. To achieve the same Servlet Filters
can be used
What
Filters
are web components like Servlet- Web container manages complete life cycle of filters
- Filter life cycle is same as Servlet except calling service methods containr invokes
doFilter
method - Filters are responsible for request pre-processing and request post-processing
- Servlets are responsible for core request processing
- Filters removes pre and post processing code duplication in each servlet
How
Like Servlets mapped towards urls using annotation, Filters can be mapped towards urls and Servlet names with annotation or via configuration in web.xml or by mixing both.
Any class which is a Filter
if it
- Implements
javax.servlet.Filter
interface - Annotated with
@WebFilter
annotation
Your filter class must has to override Filter life cycle methods
public void init(FilterConfig fConfig)
public void doFilter(ServletRequest req, ServletResponse res, FilterChain fc)
public void destroy()
Syntax
@WebFilter(description = "Demostrate how to use filter",
urlPatterns = { "*.do" },
initParams = { @WebInitParam(name = "filterName",
value = "MyFilter",
description = "The filter name") })
public class Myfilter implements Filter {
...
}
Example
You may want to capture input parameters and the IP address of the user before servlet start request processing. Once servlet completes request processing you may also want to capture the message being send by the servlet.
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// Pre-processing
System.out.println(request.getParameter("firstName"));
System.out.println(request.getParameter("lastName"));
System.out.println(request.getRemoteAddr());
// pass the request along the filter chain
// servlet core request processing - control goes to servlet
chain.doFilter(request, response);
// Post-processing
Object obj = request.getAttribute("msg");
String msg = obj.toString();
System.out.println(msg);
}
Filter life cycle
Life cycle of the Filter is same as the Servlet life cycle except that container will be calling the doFilter()
provided by the Filter
interface instead for service()
method of Servlet. A filter will be having one instance per declaration and like ServletConfig
there will be a FilterConfig
object injected inside it. FilterConfig
holds the reference to ServletContext
.
- All filters will be initialized by container at container start-up
- At the time of filter initialization
- Filter class will be loaded
- Filter instance will be created using default constructor
- Filter instance will be cast to javax.servlet.Filter
- FilterConfig object will be create
- FilterConfig object will be initialized using filter config parameter
- FilterConfig object will be initialized with ServletContext object
Filter.init
will be called by passingFilterConfig
object
- User performs pre and post processing in
Filter.doFilter
by sandwichingchain.doFilter
- At container shutdown, container calls
Filter.destroy
to release the resources
Chaining
Servlet Chaining
- Invoking multiple servlets one after another before sending response is called Servlet chaining.
- Servlet 1 calls Servlet 2, Servlet 2 calls Servlet 3 and Servlet 3 sends the response
Servlet chaining – Quick points
- Servlet chaining order cannot be controlled from outside the servlets
Filter chaining
- Invoking multiple filters one by one as chain is called as Filter chaining
- Filter chaining order can be controlled from web.xml
- Filter defined first in web.xml will be executed first
Listeners
- There are various task that are performed by web container and developer during web application execution cycle
- Some of these task binds with corresponding events
- There are listeners provided for each type of event
- When task is performed, event is triggered, listener listens to these event and react to those events
- All Listener interfaces and even classes are part of javax.servlet package
How to write listeners
Any class which
- Implements any Listener interface of javax.servlet package
- Annotated with @WebListener
is a Listener.
- Alternatively to the annotation listener can be configured in web.xml
- All methods of Listener interface must be overridden
- Container initialized by container at start up
Configure in web.xml
<listener>
<listener-class>com.atuldwivedi.learnservlet.listener.ContextListener</listener-class>
</listener>
Configure using annotation
@WebListener
public class ContextListener implements ServletContextListener {
...
}
Example
An example of writing Listener class for ServletContextListener
- ServletContextListener has two methods
- public void contextInitialized(ServletContextEvent sce)
- public void contextDestroyed(ServletContextEvent sce)
- Both methods need to be overridden in user’s Listener class
- Below is the code for the same
package com.atuldwivedi.learnservlet.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* Application Lifecycle Listener implementation class ContextListener
*
*/
@WebListener
public class ContextListener implements ServletContextListener {
/**
* Default constructor.
*/
public ContextListener() {
// TODO Auto-generated constructor stub
}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent arg0) {
ServletContext ctx = arg0.getServletContext();
System.out.println(this.getClass().getName() + " contextDestroyed "
+ ctx);
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent arg0) {
ServletContext ctx = arg0.getServletContext();
System.out.println(this.getClass().getName() + " contextInitialized "
+ ctx);
}
}
Internal working
Container startup
- Container create
ServletContext
object
ServletContext sctx = new ServletContextImpl();
- Initializes sctx with context parameters configured in web.xml
- Container creates
ServletContextEvent
object
ServletContextEvent sce = new ServletContextEvent(sctx);
- Container creates
ServletContextListener
object
ServletContextListener listener = new ServletContextListenerImpl();
- Container invokes
contexInitialized()
method ofServletContextListener
listener.contexInitialized(sce);
Container shut down
- Container invokes
contextDestryed()
method ofServletContextListener
listener.contextDestroyed(sce);
- Destroyed the
ServletContext
object