Next , we'll look specifically at how to use the Domino Java Classes from J2EE servlet applications. For servlets, we have choices as to where in the servlet life cycle to establish the Domino session and, if required for local sessions, the NotesThread context. Recall that the Web container manages a servlet through four primary stages: loading, initialization ( init() ), service handling ( doGet() , doPost() ), and destruction ( destroy() ). We could establish the Domino session and thread context in the servlet's initialization stage (and undo it in the destruction stage) or establish them for each service request. Naturally, it would be more efficient to establish the session once for the servlet in the initialization method. However, this implies that the session would be established using single user identity for all servlet requests . If a single user identity is appropriate for the servlet application, then create the Domino session in the servlet's init() method. If the Domino access needs to be made under a user identity associated with the servlet requester, then the session will have to be created within the session handling methods . As for establishing the NotesThread context for a servlet, recall that this is only required for local Domino sessions. If needed, the NotesThread context must be established for each thread invoking Domino Java objects. Since a Web container will invoke the service handling methods from multiple JVM threads (unless the servlet is defined to be single threaded), we really have no choice but to establish the NotesThread context within the service handling methods. This can be done via the NotesThread static methods, sinitThread() and stermThread() . The stermThread() method should be put in a finally clause since it must be invoked if the sinitThread() method is successful. Let's look at a sample servlet, GetBookDomino , which accesses a Domino database, "booklist.nsf," via the Domino Java classes and accesses a view within this database. We will focus on the use of the Domino classes rather than the function of the servlet itself. GetBookDomino.java: import java.io.PrintWriter; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Date; import java.util.Enumeration; import java.text.SimpleDateFormat; import lotus.domino.*; /** * GetBookDomino - Demonstrates using Domino Java classes from WAS. */ public class GetBookDomino extends HttpServlet { // Holds single Domino session, if SingleDominoSession=yes Session itsDominoSession; public void init() throws ServletException { super .init(); // See if single Domino session to be set up itsDominoSession = null ; String aSessParm = getInitParameter( "SingleDominoSession" ); if ( aSessParm != null && aSessParm.equalsIgnoreCase( "yes" ) ) { (1) NotesThread.sinitThread(); try { itsDominoSession = NotesFactory.createSession(); } catch ( NotesException e ) { System.out.println( "Error creating Domino session!" ); itsDominoSession = null ; } } } public void doGet( HttpServletRequest theReq, HttpServletResponse theResp ) throws ServletException, IOException { // Set up writer for servlet response content, write HTML heading. theResp.setContentType( "text/html" ); PrintWriter aPW = theResp.getWriter(); aPW.println( "<HTML>\n<HEAD>" + "\n<META http-equiv=\"Content-Type\"" + " content=\"text/html; charset=ISO-8859-1\">" + "\n<META http-equiv=\"Content-Style-Type\" content=\"text/css\">" + "\n<TITLE>GetBook Response</TITLE>" + "\n</HEAD> \n<BODY>\n" ); // Save the servlet request parameters. // We look for: host, user, pw, auth (these are used for createSession) String aHost = null ; String aUser = null ; String aPass = null ; Enumeration aReqParms = theReq.getParameterNames(); while ( aReqParms.hasMoreElements() ) { String aParm = (String)aReqParms.nextElement(); if ( aParm.equalsIgnoreCase( "host" ) ) aHost = theReq.getParameter( aParm ); else if ( aParm.equalsIgnoreCase( "user" ) ) aUser = theReq.getParameter( aParm ); else if ( aParm.equalsIgnoreCase( "pw" ) ) aPass = theReq.getParameter( aParm ); } aPW.println( "<br>Session parameters: Host = " + aHost + ", User = " + aUser + ", Passwd = " + aPass ); try { // Set up Domino Java thread and local session. Date aStart = new Date(); SimpleDateFormat aSDF = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); aPW.println( "<p>Servlet started: " + aSDF.format( aStart ) ); String aSessType; Session aSession = itsDominoSession; if ( aSession == null ) { (2) if ( aHost == null ) NotesThread.sinitThread(); aSession = NotesFactory.createSession( aHost, aUser, aPass ); aSessType = "created by servlet"; } else aSessType = "from servlet init"; aPW.println( "<br>Domino session " + aSessType + ", set up time (ms): " + ( ( new Date()).getTime() - aStart.getTime() ) + "<br>Session server: " + aSession.getServerName() + "<br>Connected as: " + aSession.getUserName() ); // Access Domino database we want to display, fail if not found. String aDbName = getInitParameter( "DbName" ); if ( aDbName == null ) aDbName = "booklist.nsf"; (3) Database aDb = aSession.getDatabase( null , aDbName, false ); if ( aDb != null ) { View aBooks = aDb.getView( "Books" ); if ( aBooks != null ) { aPW.println( "<p><TABLE border=\"1\">" ); aPW.println( "<TR><TH>Title</TH><TH>Author</TH><TH> Price</TH>" ); Document aDoc = aBooks.getFirstDocument(); (4) while ( aDoc != null ) { aPW.println( "<TR> <TD>" + aDoc.getItemValueString( "booktitle" ) + "</TD><TD>" + aDoc.getItemValueString( "bookauthor" ) + "</TD><TD>" + aDoc.getItemValueString( "bookprice" ) + "</TD>" ); aDoc = aBooks.getNextDocument( aDoc ); } aPW.println( "</TABLE>" ); (5) aBooks.recycle(); } else aPW.println( "<p><b>Error: Domino database view not found!</b>" ); aDb.recycle(); } else aPW.println( "<p><b>Error: Domino database not found!</b>" ); // Recycle session only if created by this servlet if ( itsDominoSession == null ) aSession.recycle(); } catch ( Exception e ) { System.out.println( "GetBookDomino error: " + e ); aPW.println( "<p><b>Servlet error: </b>" + e ); } finally { // Terminate NotesThread only if established by this servlet (6) if ( itsDominoSession == null && aHost == null ) NotesThread.stermThread(); aPW.println( "</BODY>" ); aPW.close(); } } public void destroy() { if ( itsDominoSession != null ) { try { itsDominoSession.recycle(); } catch ( NotesException e ) { System.out.println( "Error recycling single Domino session!" ); } (7) NotesThread.stermThread(); } super .destroy(); } } Here are the specific points about the servlet code. The numbered list that follows refers to the (n) annotations in the preceding code. -
The servlet is coded to set up the Domino session in the initialization method based on a servlet parameter. Here, since the session is local, we must also establish a NotesThread context. -
If a session has not been established already, the doGet method creates the session based on the host, user, and password parameters passed via the request. If a remote host is not specified, then the NotesThread context is established. Even if the NotesThread context is established during servlet initialization, it may need to be established in doGet (or the other service-handling methods) because the method may be running under a different thread than the one under which initialization was performed. We found no way to determine if NotesThread is established other than attempting a Domino object access and catching a NotesException if the access fails. -
A specific Domino database object is obtained. -
A View object is used to iterate through a set of documents in the database. Views are used in this way to act as queries on the database content. -
Domino objects should be recycled after they are done being used. The recycle method performs additional resource cleanup beyond Java garbage collection. -
The NotesThread context must be terminated if established by the service method. -
The NotesThread context must be terminated if established by servlet initialization. In order to run a servlet utilizing the Domino Java classes, the application server must have access via its Java classpath to the jar files containing the Domino Java support. For local session access, the required file is Notes.jar and for remote access it is NCSO.jar. Both of these files can be found under the Domino R6 installation path . When running the servlet under WSAD in the WebSphere Test Environment (WTE) server, you must specify the Notes and NCSO .jars to the WTE server environment file, as shown in Figure 10-1. Since our servlet can use both local and remote sessions, we specified both the Notes and NCSO .jar files. Figure 10-1. WTE path specification for Domino .jars. |