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 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.
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.
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:
If instance of the servlet does not exists, then web container
new()
methodinit()
methodContainer invoked service method(doGet()
, doPost()
, service()
etc), passing request
and response
objects
If it needs to remove the servlet, container finalizes()
the servlet by calling Servlet’s destroy()
method
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
@WebServlet("/report")
public class MoodServlet extends HttpServlet {
…
}
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
PrintWriter pw = response.getWriter();
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.
A request contains data passed between client and the servlet. All requests implements ServletRequest
interface. ServletRequest
interface defines methods for accessing the following information.
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
PrintWriter
returned by response’s getWriter
ServletOutputStream
returned by getOutputStream
ServletOutputStream
and manage the character section manuallysetContentType(String)
method is availablesetBufferSize(int)
methodjavax.servlet.http.HttpServletResponse
, have fields representing HTTP headers, such as the following. There are mainly three type of parameters
ServletRequest
parametersServletConfig
parametersServletContext
parametersUsing 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>");
}
@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 {
...
}
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>");
}
<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>");
}
RequestDispatcher rd = request.getRequestDispatcher(path + page);
RequestDispatcher rd = request.getRequestDispatcher(path + page);
rd.forward(request, response);
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);
}
RequestDispatcher rd1 = request.getRequestDispatcher(path+"header.html");
rd1.include(request, response);
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);
}
response.sendRedirect("index.html");
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");
}
}
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:
Tasks need to be done after request processing called request post-processing. Eg:
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
Filters
are web components like ServletdoFilter
methodLike 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
javax.servlet.Filter
interface@WebFilter
annotationYour 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()
@WebFilter(description = "Demostrate how to use filter",
urlPatterns = { "*.do" },
initParams = { @WebInitParam(name = "filterName",
value = "MyFilter",
description = "The filter name") })
public class Myfilter implements Filter {
...
}
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);
}
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
.
Filter.init
will be called by passing FilterConfig
objectFilter.doFilter
by sandwiching chain.doFilter
Filter.destroy
to release the resourcesAny class which
is a Listener.
<listener>
<listener-class>com.atuldwivedi.learnservlet.listener.ContextListener</listener-class>
</listener>
@WebListener
public class ContextListener implements ServletContextListener {
...
}
An example of writing Listener class for ServletContextListener
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);
}
}
ServletContext
objectServletContext sctx = new ServletContextImpl();
ServletContextEvent
objectServletContextEvent sce = new ServletContextEvent(sctx);
ServletContextListener
objectServletContextListener listener = new ServletContextListenerImpl();
contexInitialized()
method of ServletContextListener
listener.contexInitialized(sce);
contextDestryed()
method of ServletContextListener
listener.contextDestroyed(sce);
ServletContext
object