Servlets are Java technology based components that generate dynamic content, and are considered to be the core building blocks of Java based web applications.
Servlets are contained within and managed by containers, called ‘servlet engines’ or ‘servlet containers’ or ‘web containers’, which are extensions to web servers.
Servlets interact with clients through a request and response model that the servlet container implements. A servlet processes the request sent from the client via the servlet container and generates dynamic content that is sent back to the client via the servlet container.
A servlet container is part of a web server that contains and manages servlets through their lifecycle.
In addition to managing servlets, the servlet container provides the network services over which the request to and responses from the servlet are sent.
The servlet container also performs other functions such as mapping requests to servlets, decoding requests to the servlet and formatting responses that are send back from the servlet.
Servlet containers support HTTP and HTTPS as protocols for requests and responses.
Web Server - A web server processes HTTP Requests from web clients and responds back with Http Responses. A web server can process and respond to HTTP requests for static content, but it cannot process requests for dynamic content by itself.
Apache Http Server and IBM Http Server are examples of commonly used Web Servers.
Web Container - In Java based web applications the dynamic content is processed by servlets that run in a ‘web container’, also called as ‘servlet container’. Web servers utilize web containers to respond to requests for dynamic data.
A web container implements the Java Servlet specification (including JSP and JSTL). The servlet container contains and manages servlets through their lifecycle.
Apache Tomcat and Jetty are example of web/servlet containers.
Application Server - An application server contains the web container or implements the Servlet API, contains the EJB container which manages EJBs, and implements the complete Java EE specification – JMS, JTA, JNDI, JAX-RPC, JavaMail etc.
Unlike web servers, which support only Http protocol, application servers supports various protocols such as Http, TCP/IP, IIOP, RMI, JRMP etc.
The application server provides various scalability and fault-tolerance techniques, resource pooling, component life cycle management, transaction management, messaging, security etc.
IBM Websphere, Weblogic and JBoss are some of the commonly used Application servers.
The request from a web client to a server for a resource, the processing of that request by the server, and returning of the corresponding response from the server to the web client - goes through a well-defined flow.
Following are the key steps in this flow.
1. A web client accesses a web server via a browser and makes a request for a resource via the HTTP protocol.
2. The web server receives the request, and checks if the resource requested is static (HTML pages, Text files, Images etc.) or dynamic (Servlet, JSP etc.)
3.If the requested resource is static, the web server accesses the resource and returns it to the client as a response via the HTTP protocol. The static resources such as HTML files, Image files, Text files etc. are usually hosted on the web server’s publicly accessible folder system.
4. If the resource requested is dynamic, the web container forwards the request to the servlet container for further processing.
5.The servlet container determines which servlet to invoke based on the servlet mapping defined in the application’s configuration file, and calls the service() method of the servlet. The servlet container passes objects representing the request and response as arguments to the service() method of the servlet.
6.The servlet used the request object to access the parameters sent by web client, performs the program logic, generates the dynamic content and sets it within the response object.
7.After the service() method completes, the web container sends back the response with the dynamic content back to the web server.
8. The web server sends the response with the dynamic content to the client via HTTP protocol.
The Servlet API consists of two key packages – ‘javax.servlet’ and ‘javax.servlet.http’
Two other packages ‘javax.servlet.annotation’ and ‘javax.servlet.descriptor’ were introduced in version 3.0 of the API to provide annotation functionality and aggregation.
Javax.servlet - The javax.servlet package contains a number of classes and interfaces that describe and define the contracts between a servlet class and the runtime environment provided for an instance of such a class by a conforming servlet container.
Javax.servlet.http - The javax.servlet.http package contains a number of classes and interfaces that describe and define the contracts between a servlet class running under the HTTP protocol and the runtime environment provided for an instance of such a class by a conforming servlet container.
Javax.servlet.annotation - The javax.servlet.annotation package contains a number of annotations that allow users to use annotations to declare servlets, filters, listeners and specify the metadata for the declared component.
Javax.servlet.descriptor - The Javax.servlet.descriptor packageProvides programmatic access to a web application's configuration information that was aggregated from the web.xml and web-fragment.xml descriptors.
Following are the interfaces and classes defined in javax.servlet package.
Interfaces - Servlet, Filter, ServletRequest, ServletResponse, ServletContext, ServletConfig, RequestDispatcher
Classes - GenericServlet, ServletInputStream, ServletOutputStream
Following are the interfaces and classes defined in javax.servlet.http package.
Interfaces - HttpSession, HttpServletRequest, HttpServletResponse
Classes - HttpServlet, Cookie
The lifecycle methods specified in the Servlet API are the init(), service() and destroy() methods of the Servlet interface that all servlets implement either directly or indirectly through the GenericServlet and HttpServlet abstract classes.
Servlet - The Servlet interface is the base interface defined in the Java Servlet API that every servlet has to implement. Servlet interface defines the life-cycle methods of a servlet - to initialize a servlet, to service requests, and to remove a servlet from service.
Every servlet implements this interface either directly, or more commonly, by extending a class that implements this interface.
GenericServlet - GenericServlet, which implements Servlet interface defines a generic protocol-independent servlet. A servlet can directly extend GenericServlet, though it’s more common to extend a protocol-specific subclass such as HttpServlet.
HttpServlet - HttpServlet extends from GenericServlet and provides HTTP protocol specific functionality.
HttpServlet overrides the service() method to handle HTTP requests and dispatch them to one of the doXXX() handler methods depending on the Http request type (GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE).
Following are the seven doXXX() methods that the request is dispatched to from the service() method.
doGet() – Handles Http GET requests
doPost() – Handles Http POST requests
doPut() – Handles Http PUT requests
doDelete() – Handles Http DELETE requests
doHead() – Handles Http HEAD requests
doOptions() – Handles Http OPTIONS requests
doTrace() – Handles Http TRACE requests
By default, the servlet container instantiates only one instance of a servlet per JVM. The servlet container sends multiple concurrent requests to the service() method of the servlet to process, via a separate thread for each request. Hence the service() method and the servlet has to be designed to be thread safe for concurrent processing with multiple threads.
A servlet can be forced to handle only one thread at a time by implementing SingleThreadModel. In this case, the servlet container creates a new instance of the servlet for each request thread.
When a servlet implements SingleThreadModel, the servlet container guarantees that only one thread at a time accesses the service method. The servlet container does this by either serializing access to the service method or by maintaining a pool of servlet instances.
Due to performance impacts, implementing SingleThreadModel is not recommended. SingleThreadModel interface is deprecated since Servlet API version 3.0
Request Parameters - Request parameters are extra information sent from the client to the servlet container as part of its request. For HTTP servlets, request parameters are contained either in the URI query string or POST form data. The servlet container sets these parameter into an HttpServletRequest object and passes this object as an argument to the servlet’s service() method.
Request Attributes - Request Attributes are objects associated with a request. Attributes can be set by the servlet container to make custom information available about a request, or can be set programatically by a servlet to communicate information to another servlet.
Files can be send to the servlet container for processing by requests that are of type Multipart/form-data.
HttpServletRequest defines following methods for handling Multipart data.
getParts() - Gets all the Part components of this request, provided that it is of type multipart/form-data. If this request is of type multipart/form-data, but does not contain any Part components, the returned collection will be empty.
getPart(String name) - Gets the Part with the given name. The Part with the given name, or null if this request is of type multipart/form-data, but does not contain the requested Part.
The ServletRequest interface defines the following methods to read the body of the request as a stream.
getInputStream() - Retrieves the body of the request as binary data using a ServletInputStream object.
getReader() - Retrieves the body of the request as character data using a BufferedReader object. The reader translates the character data according to the character encoding used on the body.
The ServletRequest interface defines the following methods to get more information about the client or the last proxy that send the request.
getRemoteAddr() - Returns the Internet Protocol (IP) address of the client or last proxy that sent the request.
getRemoteHost() - Returns the fully qualified name of the client or the last proxy that sent the request.
getRemotePort() - Returns the Internet Protocol (IP) source port of the client or last proxy that sent the request.
HttpServletRequest interface that extends from ServletRequest interface inherits above methods.
The HttpServletRequest interface defines the following methods to access the headers of an HTTP request.
getHeader() - Returns the value of the specified request header as a String.
getHeaders() - Returns all the values of the specified request header as an Enumeration of String objects.
getHeaderNames() - Returns an enumeration of all the header names this request contains.
getIntHeader() - Returns the value of the specified request header as an int.
getDateHeader() - Returns the value of the specified request header as a long value that represents a Date object.
The HttpServletRequest interface defines a number of methods to get more information about the session that is associated with the request.
Out of these methods, following methods are important and are frequently used.
getSession() - Returns the current session associated with this request, or if the request does not have a session, creates one.
getSession(boolean create) - Returns the current HttpSession object associated with this request or, if there is no current session and create is true, returns a new session. If create is false and the request has no valid HttpSession, this method returns null.
A servlet can check if a request has been transmitted over a secure protocol, such as HTTPs, by calling the isSecure() method of the ServletRequest interface.
The ServletRequest interface defined in Servlet API provides the following methods for authentication.
authenticate() - Uses the container's login mechanism configured for the ServletContext to authenticate the user making this request.
getAuthType() - Returns the name of the authentication scheme used to protect the servlet.
getUserPrincipal() - Returns a java.security.Principal object containing the name of the current authenticated user.
isUserInRole() - Returns a boolean indicating whether the authenticated user is included in the specified logical role.
login() - Validate the provided username and password in the password validation realm used by the web container login mechanism configured for the ServletContext.
logout() - Establish null as the value returned when getUserPrincipal(), getRemoteUser(), and getAuthType() is called on the request.
ServletContext.getRequestDispatcher() method takes a String argument describing a path within the scope of the ServletContext. This path must be relative to the root of the ServletContext and begin with a ‘/’, or be empty.
ServletRequest.getRequestDispatcher() method takes a String argument describing a path relative to the path of the current request.
include() - The include() method defined in RequestDispatcher interface sets the contents of a resource (servlet, JSP page, HTML file) in the response. Basically, this method enables programmatic server-side includes.
forward() The forward() method defined in RequestDispatcher interface forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server. This method allows one servlet to do preliminary processing of a request and another resource to generate the response.
Following are the key differences between RequestDispatcher.forward() and ServletResponse.sendRedirect() methods.
1. RequestDispatcher.forward() sends the request from one resource (servlet or JSP) to another resource via the servlet container. ServletResponse.sendRedirect() sends the request to another resource via the browser
2. RequestDispatcher.forward() sends the request from one resource to another resource within the same domain and context. ServletResponse.sendRedirect() sends the request to another resource that may be on a different domain or server.
2. RequestDispatcher.forward() preserves the request and response object and sends them to the new resource. ServletResponse.sendRedirect() does not preserve the request and response objects. These are not send to the new resource.
3. RequestDispatcher.forward() method is not transparent to the client. The URL on the browser does not change. RequestDispatcher.forward() method is transparent to the client. This is a new request from the browser and the browser URL changes.
4. RequestDispatcher.forward() is faster than ServletResponse.sendRedirect()
You can use ServletResponse object to send the response text back to the client.
The ServletResponse interface defines following two methods that return streams which can be used to set content to send back to the client.
getOutputStream() - Returns a ServletOutputStream object which is suitable for writing binary data.
getWriter() - Returns a PrintWriter object which is suitable for writing character data to the response.
The servlet container usually buffers output going to the client to increase efficiency. The servlet container allows servlet to specify buffering parameters.
The ServletResponse interface provides the following method that allow the servlet to set buffering information.
setBufferSize() – Sets the buffer size. This method must be called before content is written using a ServletOutputStream and writer.
You can set HTTP headers on the response to the client by calling the setHeader() method on HttpServletResponse interface.
You can set HTTP headers on the response to the client by calling the setHeader() method on HttpServletResponse interface.