Oracle JavaServer Pages Developer's Guide and Reference Release 8.1.7 Part Number A83726-01 |
|
This section has examples of how the Oracle globals.jsa
mechanism can be used in servlet 2.0 environments to provide an application framework and application-based and session-based event handling. The following examples are provided:
For information about globals.jsa
usage, see "OracleJSP Application and Session Support for Servlet 2.0".
This sample illustrates OracleJSP globals.jsa
event handling through the application_OnStart
and application_OnEnd
event handlers. In this sample, numbers are cached on a per-user basis for the duration of the day. As a result, only one set of numbers is ever presented to a user for a given lottery drawing. In this sample, a user is identified by their IP address.
Code has been written for application_OnStart
and application_OnEnd
to make the cache persistent across application shutdowns. The sample writes the cached data to a file as it is being terminated and reads from the file as it is being restarted (presuming the server is restarted the same day that the cache was written).
<%@ page import="java.util.*, oracle.jsp.jml.*" %> <jsp:useBean id = "cachedNumbers" class = "java.util.Hashtable" scope = "application" /> <event:application_OnStart> <% Calendar today = Calendar.getInstance(); application.setAttribute("today", today); try { FileInputStream fis = new FileInputStream (application.getRealPath("/")+File.separator+"lotto.che"); ObjectInputStream ois = new ObjectInputStream(fis); Calendar cacheDay = (Calendar) ois.readObject(); if (cacheDay.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR)) { cachedNumbers = (Hashtable) ois.readObject(); application.setAttribute("cachedNumbers", cachedNumbers); } ois.close(); } catch (Exception theE) { // catch all -- can't use persistent data } %> </event:application_OnStart> <event:application_OnEnd> <% Calendar now = Calendar.getInstance(); Calendar today = (Calendar) application.getAttribute("today"); if (cachedNumbers.isEmpty() || now.get(Calendar.DAY_OF_YEAR) > today.get(Calendar.DAY_OF_YEAR)) { File f = new File(application.getRealPath("/")+File.separator+"lotto.che"); if (f.exists()) f.delete(); return; } try { FileOutputStream fos = new FileOutputStream (application.getRealPath("/")+File.separator+"lotto.che"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(today); oos.writeObject(cachedNumbers); oos.close(); } catch (Exception theE) { // catch all -- can't use persistent data } %> </event:application_OnEnd>
<%@ page session = "false" %> <jsp:useBean id = "picker" class = "oracle.jsp.sample.lottery.LottoPicker" scope = "page" /> <HTML> <HEAD><TITLE>Lotto Number Generator</TITLE></HEAD> <BODY BACKGROUND="images/cream.jpg" BGCOLOR="#FFFFFF"> <H1 ALIGN="CENTER"></H1> <BR> <!-- <H1 ALIGN="CENTER"> IP: <%= request.getRemoteAddr() %> <BR> --> <H1 ALIGN="CENTER">Your Specially Picked</H1> <P ALIGN="CENTER"><IMG SRC="images/winningnumbers.gif" WIDTH="450" HEIGHT="69" ALIGN="BOTTOM" BORDER="0"></P> <P> <P ALIGN="CENTER"> <TABLE ALIGN="CENTER" BORDER="0" CELLPADDING="0" CELLSPACING="0"> <TR> <% int[] picks; String identity = request.getRemoteAddr(); // Make sure its not tomorrow Calendar now = Calendar.getInstance(); Calendar today = (Calendar) application.getAttribute("today"); if (now.get(Calendar.DAY_OF_YEAR) > today.get(Calendar.DAY_OF_YEAR)) { System.out.println("New day...."); cachedNumbers.clear(); today = now; application.setAttribute("today", today); } synchronized (cachedNumbers) { if ((picks = (int []) cachedNumbers.get(identity)) == null) { picks = picker.getPicks(); cachedNumbers.put(identity, picks); } } for (int i = 0; i < picks.length; i++) { %> <TD> <IMG SRC="images/ball<%= picks[i] %>.gif" WIDTH="68" HEIGHT="76" ALIGN="BOTTOM" BORDER="0"> </TD> <% } %> </TR> </TABLE> </P> <P ALIGN="CENTER"><BR> <BR> <IMG SRC="images/playrespon.gif" WIDTH="120" HEIGHT="73" ALIGN="BOTTOM" BORDER="0"> </BODY> </HTML>
This example uses a globals.jsa
file to process applications and session lifecycle events. It counts the number of active sessions, the total number of sessions, and the total number of times the application page has been hit. Each of these values is maintained at the application
scope. The application page (index1.jsp
) updates the page hit count on each request. The globals.jsa session_OnStart
event handler increments the number of active sessions and the total number of sessions. The globals.jsa session_OnEnd
handler decrements the number of active sessions by one.
The page output is simple. When a new session starts, the session counters are output. The page counter is output on every request. The final tally of each value is output in the globals.jsa application_OnEnd
event handler.
Note the following in this example:
application
scope.
oracle.jsp.jml.JmlNumber
extended datatype. This is a built-in bean that simplifies the use of data values at application scope. (For information about the JML extended datatypes, see "JML Extended Datatypes".)
<%@ taglib uri="oracle.jsp.parse.OpenJspRegisterLib" prefix="jml" %> <event:application_OnStart> <%-- Initializes counts to zero --%> <jsp:useBean id="pageCount" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <jsp:useBean id="sessionCount" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <jsp:useBean id="activeSessions" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <%-- Consider storing pageCount persistently -- If you do read it here --%> </event:application_OnStart> <event:application_OnEnd> <%-- Acquire beans --%> <jsp:useBean id="pageCount" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <jsp:useBean id="sessionCount" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <% application.log("The number of page hits were: " + pageCount.getValue() ); %> <% application.log("The number of client sessions were: " + sessionCount.getValue() ); %> <%-- Consider storing pageCount persistently -- If you do write it here --%> </event:application_OnEnd> <event:session_OnStart> <%-- Acquire beans --%> <jsp:useBean id="sessionCount" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <jsp:useBean id="activeSessions" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <% synchronized (sessionCount) { sessionCount.setValue(sessionCount.getValue() + 1); %> <br> Starting session #: <%= sessionCount.getValue() %> <br> <% } %> <% synchronized (activeSessions) { activeSessions.setValue(activeSessions.getValue() + 1); %> There are currently <b> <%= activeSessions.getValue() %> </b> active sessions <p> <% } %> </event:session_OnStart> <event:session_OnEnd> <%-- Acquire beans --%> <jsp:useBean id="activeSessions" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <% synchronized (activeSessions) { activeSessions.setValue(activeSessions.getValue() - 1); } %> </event:session_OnEnd>
<%-- Acquire beans --%> <jsp:useBean id="pageCount" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <% synchronized(pageCount) { pageCount.setValue(pageCount.getValue() + 1); } %> This page has been accessed <b> <%= pageCount.getValue() %> </b> times. <p>
This example uses a globals.jsa
file to declare variables globally. It is based on the event handler sample in "globals.jsa Example for Application and Session Events--index1.jsp", but differs in that the three application counter variables are declared globally. (In the original event-handler sample, by contrast, each event handler and the JSP page itself had to provide jsp:useBean
statements to locally declare the beans they were accessing.)
Declaring the beans globally results in implicit declaration in all event handlers and the JSP page.
<%-- globally declares variables and initializes them to zero --%> <jsp:useBean id="pageCount" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <jsp:useBean id="sessionCount" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <jsp:useBean id="activeSessions" class="oracle.jsp.jml.JmlNumber" scope = "application" /> <event:application_OnStart> <%-- Consider storing pageCount persistently -- If you do read it here --%> </event:application_OnStart> <event:application_OnEnd> <% application.log("The number of page hits were: " + pageCount.getValue() ); %> <% application.log("The number of client sessions were: " + sessionCount.getValue() ); %> <%-- Consider storing pageCount persistently -- If you do write it here --%> </event:application_OnEnd> <event:session_OnStart> <% synchronized (sessionCount) { sessionCount.setValue(sessionCount.getValue() + 1); %> <br> Starting session #: <%= sessionCount.getValue() %> <br> <% } %> <% synchronized (activeSessions) { activeSessions.setValue(activeSessions.getValue() + 1); %> There are currently <b> <%= activeSessions.getValue() %> </b> active sessions <p> <% } %> </event:session_OnStart> <event:session_OnEnd> <% synchronized (activeSessions) { activeSessions.setValue(activeSessions.getValue() - 1); } %> </event:session_OnEnd>
<%-- pageCount declared in globals.jsa so active in all pages --%> <% synchronized(pageCount) { pageCount.setValue(pageCount.getValue() + 1); } %> This page has been accessed <b> <%= pageCount.getValue() %> </b> times. <p>
|
Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
|