|
|
|
Websites that are application intensive typically have hundreds of server side operations that can be performed. While using servlets to develop the server side applications, a major design decision has to be made - the organization of the servlets themselves with respect to the kind of functionality that each one of them has to provide and the manner in which they will be invoked. One option would be to have a single servlet representing each function of the site. For very large application sites, this could become very cumbersome... more so when there is a team is working on the application. When functionality is added or changed, the corresponding servlets demanded changes as well. Another alternative would be to have a single servlet manage all of the operations, but this has to be ruled out considering the number of operations that have to be accomodated. The resulting mass of if-else conditions would be a programmer's nightmare! A halfway solution to the problem is using a single servlet used in conjunction with Java’s feature of "class reflection" - the Smart Servlet. This servlet could behave dynamically based on what parameters are passed to it. This design also separates the presentation from the business logic. This can be done by using the Smart Servlet to manage receiving processing parameters, process selection, and presenting the results, while using ordinary Java classes to perform the actual processing. To illustrate a very basic example of this design appraoch, we assume that there are 3 classes op1, op2 and op2. These classes handle the business logic of 3 operations - Operation 1, Operation 2 and Operation 3 respectively. These classes are extended from the same parent class Operation. The parent class can contain elements that are common to all the child classes. The smart servlet is named OperationManager. Take a look at the HTML document that actually calls the servlet and passes parameters to it: <html> <head> <title>Smart Servlet Example</title> </head> <body> <H1>Smart Servlet Demo</H1><p> To execute servlet: type in parameters, select an operation, then click the "Invoke Servlet" button.<p> <form method=get action='/servlet/OperationManager'> <b>Parameter One:</b> <input type=text name="param1"><p> <b>Parameter Two:</b> <input type=text name="param2"><p> <b>Parameter Three:</b> <input type=text name="param3"><p> <b>Operation:</b><nbsp> <select name="operation"> <option value="op1">Operation 1 <option value="op2">Operation 2 <option value="op3">Operation 3 </select> <input type=submit value='Invoke Servlet'> </form> </body></html> There are 3 parameters which will be used to perform the business logic part of the operation. The select box lists the operations that can be performed. When the operation to be performed is chosen and parameters are specified, the form is submitted to the servlet. This is done by the value of the action property of the form tag. In this case, the servlet is OperationManager. A code snippet from the OperationManager class will give an idea of how the request is handled.
public class OperationManager extends HttpServlet
{
public doPost(HttpServletRequest request, HttpServletResponse response)
{
try
{
Class operClass;
HttpSesssion session = request.getSession(true);
// determine the class to instantiate
operClass = Class.forName(request.getParameter("operation"));
//instantiate the class
Operation oper = (Operation)operClass.newInstance();
// retrieve all the other parameters received from the client
Enumeration enum = request.getParameterNames();
Hashtable hTable = new Hashtable();
String paramName;
// put all parameters into a hash table
while(enum.hasMoreElements())
{
param = enum.nextElement();
hTable.putValue(param, request.getParameter(param));
}
oper.setValues(hTable);
//code for presentation
....
}
catch(ClassNotFoundException e)
{
//handle exceptions
...
It must be pretty clear by now that we have to follow certain conventions in this design. The first being that all HTML documents should contain a input parameter that can be used by the servlet to determine the class to be instantiated.
Second, all non-servlet classes that are being instantiated by the servlet should implement the method public setValues(HashTable). This method retrieves all the parameter names received by the servlet from the client. It would be
a good idea to implement this method as a part of the ancestor class. The classes themselves should have methods which retrieves the values from the hash table. Third, all classes should have methods which can be called by the servlet to
determine the response to be sent to the client. A method like public StringBuffer getHTML() which returns the response to be sent to the client could be used. The response is formatted for presentation by the servlet.
In conclusion, we can say that this design approach has its advantages - single point entry into server side application allowing for easier and more robust session management, separation of presentation and business logic, scalability
and easier management of application functionality. All this provided the conventions mentioned are adhered to.
For comments and suggestions, mail me at vikramr@planetasia.com.
|