Hi,

Here's my favorite way to organize software that uses servlets:

- Have server objects that implement well-defined interfaces.
- Have servlets that act as bridges between the Java world and the HTTP world.

With this, your app logic is independent of the network protocol.  This reduces
the "importance" of servlets.  It then makes your system more flexible - it could
also accept CORBA and RMI requests, not just HTTP ones.

The one issue I need to resolve is how to abstract the servlet's cool session
ability.  I don't want to get "tied" to it.

Here's a pretty extreme case that's an example of a typical servlet I write.  The
only changes needed to be made are to factor out the authentication code.  Note
how I bridge between HTTP and Java by:

1. Changing HTTP parameters to method parameters
2. Changing Java exceptions to HTTP error codes

- Robb

package topas.xrb;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import topas.util.TimeoutException;


/**
 * This will become the new Middleware Servlet.  This class
 * is responsible for everything that has to do with hooking
 * up the middleware server (XrbServer) to the HTTP
 * infrastructure.<p>
 *
 * It is a servlet, and so doesn't have to worry about most
 * HTTP details.  It manages the cookies and packs id's into
 * them.  It's responsible for creating a new id, because it
 * knows when one is needed, but the actual task of generating
 * an id is delegated to XrbServer because that has to do
 * with the middleware logic, not HTTP.<p>
 *
 * <h2>Bugs</h2>
 * <ul>
 *   <li> An empty server response cannot be sent.  If the
 *        server attempts to do this, this middletier will
 *        return a 1 character response containing a space.
 *        This is due to a bug in ServletExec, the servlet
 *        engine currently in use.
 * </ul>
 *
 * @author Robb Shecter
 **/
public class MessageServlet extends HttpServlet implements XrbConstants {
    private XrbServer server;

    /**
     * This is my session key for the user id.
     **/
    static final String USER_ID = "user id";


    /**
     * Initialize myself
     **/
    public void init(ServletConfig config) throws ServletException {
 super.init(config);
 server = XrbServer.instance();
 Locale.setDefault( Locale.US );
    }



    /**
     * Handle either GET or POST
     **/
    public void doGet( HttpServletRequest req, HttpServletResponse res)
 throws ServletException, IOException {
 doPost(req,res);
    }



    /**
     * Handle either GET or POST
     **/
    public void doPost( HttpServletRequest req, HttpServletResponse res)
 throws ServletException, IOException {

 String sessionid, userid, servicename, parameter, response;
 HttpSession session;

 /*
  * Create/retrieve the session, and get its id.
  */
 session   = req.getSession(true);
 sessionid = session.getId();
 userid    = (String) session.getValue(USER_ID);

 if (userid == null) {
     /*
      * The user is not authenticated.  A production system would
      * probably return an error code 401, saying that the user
      * must log in.  For now, though, we'll just call the user
      * "guest".
      *
      * This code should be moved to the base class.
      */
     userid = DEFAULT_USER_ID;
     session.putValue(USER_ID, userid);
 }

 /*
  * Get the request parameters
  */
 servicename = req.getParameter("servicename");
 parameter   = req.getParameter("parameter");
 if (servicename == null) {
     res.sendError(400, "No servicename was specified");
     return;
 }

 log("\""+servicename+"\" requested by: "+userid+"@"+req.getRemoteHost());


 /*
  * Process the request.  Catch all possible java exceptions,
  * and create appropriate HTTP error responses. This is one
  * of the key responsiblities of a servlet class: to map responses
  * between the OO Java world and the HTTP networking world.
  */
 try {
     response = server.handleRequest(userid, sessionid, servicename, parameter);
     sendResponse(response, res);
 }

 /*
  * Return 404 if the service is not registered.
  */
 catch (NoSuchMethodException e) {
     res.sendError(404,
     "The service \""+e.getMessage()+"\" was not found." );
 }

 /*
  * Return 499 if the internal format of the parameter is
  * invalid, as tested against the server's DTD.
  */
 catch (ParameterFormatException e) {
     res.sendError(499,
     "The parameter sent to the service, '"+
     e.getServiceName()+"', does not conform to "+
     "the DTD: "+e.getDTD());
 }

 /*
  * Return 504 if the service timed out.  Note that TimeoutException
  * extends IOException, so it must come first.
  */
 catch (TimeoutException e) {
     res.sendError(504, "The service \""+servicename+"\" timed out.");
 }


 /*
  * Return 506 if the server itself threw an exception.
  */
 catch (ServerSideException e) {
     System.err.println("SSE: sendError(506, "+e.toXML()+")");
     res.sendError(506, e.toXML());
 }


 /*
  * Return 503 if the service cannot be contacted.
  */
 catch (IOException e) {
     res.sendError(503,
     "The service: '"+servicename+"', could not be "+
     "completed: "+e.getMessage());
 }

 /*
  * Return 500 if the XRB has run out of memory.
  */
 catch (OutOfMemoryError e) {
     res.sendError(500, e.toString());
 }

 /*
  * Catch any misc. exceptions that haven't
  * yet been caught.
  */
 catch (Throwable t) {
     log("WEIRD EXCEPTION", t);
     throw new ServletException(t);
 }

    }



    /**
     * Send the given xml response to the client
     **/
    private void sendResponse(String xml, HttpServletResponse res)
 throws IOException {

 if (xml.equals(""))  // This is required for ServletExec.
     xml = " ";

 res.setContentType("text/xml");
 PrintWriter out = res.getWriter();
 out.print(xml);
 out.close();
    }

}

___________________________________________________________________________
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff SERVLET-INTEREST".

Archives: http://archives.java.sun.com/archives/servlet-interest.html
Resources: http://java.sun.com/products/servlet/external-resources.html
LISTSERV Help: http://www.lsoft.com/manuals/user/user.html

Reply via email to