Through this tutorial i will try to get you closer to the Java Servlet Model. Before we start with examination of classes defined within the servlet specification, i will explain basic stuff needed to know before you start with developing web application.
Understanding the Java Servlet Models
First of all Java Servlet Model is not defined only for the web application that is specification which is based on request and response programing model. But basically it’s most used in interaction with HTTP protocol, so from now we will disussing using of servlet model in http applications.
In basically, the web applications should be applications placed somewhere on the web, and they can be accessed through the net. If you need more information and better definition of “What is a web application” you can visit next link: Web application.
If we want to create a web application we should have a web server, it can be any kind of HTTP server with included web container such as Tomcat. HTTP server is charged for handling clients request, security, servicing content to client etc. , but the HTTP server can not dynamically create response to the client he is able to serve static content. Solution of this problem is a Web Container. Container is able to hosts web application, HTTP server will pass request to the web container which will take care of the request. Usually there is only one container per Server. And all web application on the server are served by this container.
All communication inside of Web container is realized through the web container interface. It means that one application can not directly access to the another one. Also components inside one application can not access directly each others, also all communication betwean components in same application is realized using web container interface. This is very important in understanding how web application works in web container, this allow as to create filters, listeners and it allow as to use security feature of web container.
War Application Structure
By specification Java Web application is packed into war package.
War package is same as jar package,but when web container find war file in deploy folder it will assume that it is a web application and it will try to start it.
Inside of war package we have one special directory called WEB-INF.
Content of this folder is not directly served to the user. This folder contains folders classes and lib in which we can put class used by application (classes folder) and additional jars (lib folder). Content of those folders will be automatically read by class loader without any additional settings for class path. Also this folder contains web.xml file which is called deployment description. This file is not required if web application contains only jsp pages, but if application need to have servlets or filters this file must be defined.
Servlet Life Cycle
During its existing , servlet pass through the five life cycles:
Loading is phase in which class loader load a class. Every web application will get a different instance of class loader which will be used for loading web components. This allow as to deploy two version of same application in same container and every application may have classes with same name (full class name).
After loading, web container will try to instantiate class, (i.e. to create a new instance of class). Usually every web component is created just once, but this depend on behavior of web container, in some case a web container can be set to create more instance of component class in the pool, and serve request with one of instance from pool. When web container create new instance of servlet it use a default constructor.
Initialization is life cycle phase in which servlet is initialized. In this phase is supposed to servlet read some values and do some additional action and steps before servlet is able to serve client request.
Serving phase is cycle in servlet life in which servlet serving clients requests.
Destroy phase is last phase in servlet life and it happen when a servlet is removed from service.
If we want to create a servlet everything what should be done is implementing of Servlet interface.
This interface provide next three method, which are called by container:
- init(ServletConfig config), called during initialization
- service(ServletRequest request, ServletResponse response), called during servicing a request
- destroy(), called when servlet is removed from service.
Also this interface provide two ancillary
- ServletConfig getServletConfig()
- String getServletInfo()
During initialization it is possible to get ServletException. Raising of this exception in init method will signal container that some error occurred and container will stop initialization and mark servlet instance as ready for garbage collector and this will not cause calling of the destroy method.
Also during service method it is possible to get ServletException or UnavailableException. This exceptions can be temporary or permanent. In case of temporary exception server will block calling of service method for some time, but in case of permanent exception destroy method will be called and servlet will be ready for garbage collector, and every future call to this servlet will lead to 404 response.
GenericServlet class is part of javax.servlet package. It is an abstract class which implementing Servlet interface and create basic implementation which do not depend on platform.
This class introduce one new method:
- init(), called by init(ServletConfig config) method, during initialization phase
- ServletContext getServletContext(), provide access to the ServletContex
- String getInitParameter(String name), retrieve value of servlet config parameter defined in application descriptor for specified name
- Enumeration getInitParameterNames(), return an enumeration of all servlet init parameters.
- String getServletName(), return name of servlet.
If we extend GenericServlet class instead of implementing Servlet interface, only stuff what we should do is implementing of service method, all other method are already implemented by abstract class.
This is also abstract class like GenericServlet, but this class is not platform independent. It is tied to HTML protocol, and introduce new method which are only related to HTTP protocol. Every of this new methods is responsible for processing client request for particular HTTP method.
The doXxx methods:
- doGet(HttpServletRequest request, HttpServletResponse response), process get request
- doPost(HttpServletRequest request, HttpServletResponse response), process post request
- doOptions(HttpServletRequest request, HttpServletResponse response), process HTTP options request
- doPut(HttpServletRequest request, HttpServletResponse response), process HTTP put request
- doDelete(HttpServletRequest request, HttpServletResponse response), process HTTP delete request
- doHead(HttpServletRequest request, HttpServletResponse response), process HTTP head request
- doTrace(HttpServletRequest request, HttpServletResponse response), process HTTP trace request.
ServletContext interface is API which provide access to information about application. Every application is executed inside of own context, so this interface provide access to that information. Implementation of this interface is provided by server vendor and we should not be interested by concrete implementation. When application is deployed container will first create ServletContext implementation class and fill it with data provided by application descriptor.
Methods inside this interface we can split in few groups:
- Method for accessing context attribute:
- Object getAttribute(String name), retrieve object from context
- Enumeration getAttributeNames(), retrieve attributes names
- void removeAttribute(String name), remove attribute from context
- void setAttribute(String name, Object value), add new object into context and bind it by specifed name. If object with specified name already exists it will be owerridden.
- Methods for obtaining context information:
- String getServletContextName(), retrieve value defined by <display-name> in application descriptor, if not exists retriev null.
- String getRealPath(String path), context relative path of specified resource, null if application is deployed as WAR (if it not exploded in folder).
- Set getResourcesPaths(String path), retrieve files inside specified partial path, only one level
- ServletContext getContext(String appURL), retrieve ServletContex of another application deployed on same server. Url must start with ‘/’
- Methods for accessing static resources:
- URL getResource(String path), retrieve URL of resource specified by path. Path must start with ‘/’
- InputStream getResourceAsStream(String path), retrieve InputStream of specifed resource. Path can be context relative.
- String getMimeType(String path), return mie type of resource.
- Methods for obtaining request dispatcher :
- RequestDispatcher getRequestDispatcher(String path), return RequestDispatcher for specified resource or null if resource do not exists.
- RequestDispatcher getNamedDispatcher(String name), return RequestDispatcher for named resource inside of deployment descriptor.
- Methods for accessing context initialization parameters:
- String getInitParameter(String name), retrieve value for specified parameter defined in deployment descriptor, or null if it does not exists.
- Enumeration getInitParameterNames(), list of parameter names defined in applications deployment desriptor.
Context attributes are application scoped attributes, which means that all clients share same attributes, change on attribute made by one client is visible to every other clients.
This is API which provide methods for accessing information defined inside deployment descriptor. Concrete
object is created by servlet container and provided to servlet during initialization phase. This interface define next methods:
- String getInitParameter(String name), get value of init parameter defined for the servlet with specified name, or null if there is no such parameter.
- Enumeration getInitParameterNames(), retrive enumeration of servlet init parameters names.
- ServletContext getServletContext(), retrieve servlet context.
- String getServletName(), retrieve servlet name specifed in web.xml
As you can see the ServletConfig proviede only methods for reading init parameter and there is no method for changing or adding new init parameter because they cant be changed or added.
Servlets Deployment Description
If we want to use servlets we need to define them inside of deployment descriptor.
<servlet> <description>This is a servlet</description> <display-name>First Servlet</display-name> <servlet-name>FirstServlet</servlet-name> <class>ba.codecentric.scwcd.FirstServlet</class> <init-param> <param-name>firstParam</param-name> <param-value>value</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>FirstServlet</servlet-name> <uri-pattern>/FirstServlet</uti-pattern> </servlet-mapping>
Inside of servlet tags we defined servlet, inside of servlet tag we can use init param tag for defining initialization parameters, which will be sent to servlet during initialization phase as part of ServletConfig object.
And with the servlet mapping tags we define uri pattern which will be used for activeting specified servlet.
Also during this tutorial i spoken about ServletContext, and I have mentioned context parameters. These parameters are also defined in deployment description using context param tag.
<context-param> <param-name>contextParameter</param-name> <param-value>value</param-value> </context-param>