Tuesday, May 13, 2008

All About Servlets : Introduction

The Servlet Philosophy
To write a server side program , need two things
  1. Program at socket level .. handle all the incoming requests
  2. Program at logical level .. write the correct response to each request
The Servlet API is based on simple philosophy , letting the programmers concentrate on the second option and taking care of first option by themselves.

Load On Startup
The element load-on-startup indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the Web application. The element content of this element must be an integer indicating the order in which the servlet should be loaded.
  1. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses.
  2. If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-startup value.
When is destroy( ) called ?
I could think of following cases...
  1. When your application is stopped
  2. Servlet Container shuts down
  3. In init( ) method if an exception is thrown
What if i call the destroy( ) explicitly
othing , it will just execute like a normal java method call it wont unload the servlet. The unloading happens only if the Container calls the destroy( ).

From the Spec

The servlet container is not required to keep a servlet loaded for any particular period of time. A servlet instance may be kept active in a servlet container for a period of milliseconds, for the lifetime of the servlet container (which could be a number of days, months, or years), or any amount of time in between.

When the servlet container determines that a servlet should be removed from service, it calls the destroy method of the Servlet interface to allow the servlet to release any resources it is using and save any persistent state. For example, the container may do this when it wants to conserve memory resources, or when it is being shut down.

Before the servlet container calls the destroy method, it must allow any threads that are currently running in the service method of the servlet to complete execution, or exceed a server-defined time limit.

Once the destroy method is called on a servlet instance, the container may not route other requests to that instance of the servlet. If the container needs to enable the servlet again, it must do so with a new instance of the servlet’s class.

After the destroy method completes, the servlet container must release the servlet instance so that it is eligible for garbage collection.

Can I use a constructor instead of init(ServletConfig) ?
Servlet constructor can be overriden .. not be private , protected , nor default The constructor will be called by the container. In the constructor it doesn't understand classes like ServletContext and ServletConfig.

It is possible to have a custom constructor for a servlet, so long as you also add a default constructor with no arguments the servlet gets instantiated by the container dynamically java does not allow to call parametrized constuctor for dynamically loaded clases

It is possible to have a custom constructor for a servlet, so long as you also add a default constructor with no arguments, but constructors are not called in the standard servlet lifecycle. Servlets are usually instantiated by the servlet container using the Class.newInstance() method, with no arguments. At this point, the servlet has no reference to its configuration or the general servlet context, so it cannot do any useful start-up activity. These configuration references are only available through the init(ServletConfig) method.

Why is it necessary to call super.init(config)?

Programmers are expected to call the super.init(ServletConfig) in the init(ServletConfig) method so that the abstract superclass implementation of the method in GenericServlet stores the servlet configuration object. When the configuration object is stored in this way, the servlet methods getInitParameter(String) and getInitParameterNames() can be called instead of calling the equivalent methods on the configuration object.

Should I get my database connection in the init() method?

The init(ServletConfig) method is only called once when a servlet is brought into service by the servlet container, not for each new servlet thread. If you create a single database connection in the init(ServletConfig) method and use it to all handle servlet requests, you must ensure all operations are synchronized or you will get unpredictable results. You must also ensure the connection is closed when the servlet is taken out of service by overriding the servlet's destroy() method.

Generally it is better to use the init(ServletConfig) method to register the database driver and get a reference to the DriverManager, a DataSource or database connection pool. Then use the connection provider to get a connection for each request within a try/catch block. This way you can handle the case where the connection fails, and ensure that all connections are closed in any case. The close() method of a pooled Connection instance just returns it to the pool.

What's the difference between ServletConfig and ServletContext?

The ServletContext object - represents the context for the whole Web application in which a servlet is deployed, and contains initialisation parameters that are shared amongst all servlets in the application.
The ServletConfig object - represents the configuration for a single specific servlet.

How can I load a Properties file for my servlet?

There are standard methods for identifying and loading this type of static property set into servlets via the ServletContext object. The primary method is getResourceAsStream(String path), which opens an InputStream to the path given in the argument. The path must begin with a forward slash, /, and is relative to the context root, so for instance you might use the path:

Is it possible to overload the destroy() method?

Any Java method may be overloaded, but the overloaded version will not be called directly by a servlet container's lifecycle methods. The servlet container expects all servlets to have a standard no argument destroy() method, so your servlet is safe to use destroy methods with other signatures.
    public void destroy(final String arg) {
// Overloaded method body

Can I call destroy() from the service() method ?

The destroy() method has a special significance in the servlet lifecycle when it is called by the servlet container, but is a normal method in all other respects. If you have a typical destroy() method that does servlet clean-up work before the servlet is taken out of service, it is difficult to imagine why you would want to call it from the service() method, though it is possible. Normally, you should handle service requests by overriding the relevant doGet() or doPost() method.

What happens if I call destroy() from init() ?

If the destroy() method is called from the init(ServletConfig) method, whatever statements are contained in the method will be executed and the method will return, it will not affect the lifecycle status of the servlet from the container's point of view. If the init(ServletConfig) method returns without exception, the servlet container will put the servlet into service regardless.

If an exception is thrown in your init(ServletConfig) method, it may be appropriate to use the destroy() method to help handle the case. If so, you should still throw a ServletException to ensure the servlet is not put into service in this state.

Can have Static method in Servlet .. If yes , who can call it ??
Probably no one is stopping other classes to use servlet to instantiate and use it as a normal object Other classes may even call init() service() and then destroy() that wont make a java object a servlet.. unless container calls the same methods Only container can use java class as a servlet.

To sum up basically a Servlet first becomes a Java object and then a Servlet. I mean a container will first make a Java Object then convert it to Servlet Instance.

You can very well use this as a java object ( in case you call destroy( ) from init( ) etc) but it wont effect the lifeCycle of a servlet. Life cycle of servlet is decided and executed by container servlets cant manage / change their own life cycle by calling there methods.

No comments: