You used the computeFactorial method to compute the factorial in Listings 35.1 and 35.6, Factorial.jsp and ComputeFactorial.jsp. You defined the method in both examples. You could have defined the method in a class and shared it in both examples. Normally you create an instance of a class in each program and use it in that program. This method is for sharing the class, not the object. JSP allows you to share the object of a class among different pages.To enable an object to be shared, its class must be a JavaBeans component. Recall that a class is a JavaBeans component if it has the following three features:
The class is public.
The class has a public constructor with no arguments.
The class is serializable. (This requirement is not necessary in JSP.)
To create an instance for a JavaBeans component, use the following syntax:
<jsp:useBean id = "objectName" scope = "scopeAttribute" class = "ClassName" />
This syntax is equivalent to
<% ClassName objectName = new ClassName() %>
except that the scope attribute specifies the scope of the object, and the object is not recreated if it is already within the scope. Listed below are four possible values for the scope attribute:
application specifies that the object is bound to the application. The object can be shared by all sessions of the application.
session specifies that the object is bound to the client's session. Recall that a client's session is automatically created between a Web browser and a Web server. When a client from the same browser accesses two servlets or two JSP pages on the same server, the session is the same.
page is the default scope, which specifies that the object is bound to the page.
request specifies that the object is bound to the client's request.
When <jsp:useBean id="objectName" scope="scopeAttribute" class="ClassName"/> is processed , the JSP engine first searches for an object of the class with the same id and scope. If found, the preexisting bean is used; otherwise , a new bean is created.
Here is another syntax for creating a bean:
<jsp:useBean id = "objectName" scope = "scopeAttribute" class = "ClassName" > statements </jsp:useBean>
The statements are executed when the bean is created. If a bean with the same ID and class name already exists in the scope, the statements are not executed.
Listing 35.8 creates a JavaBeans component named Count and uses it to count the number of visits to a JSP page, as shown in Figure 35.6.
The JavaBeans component is named Count.java (Listing 35.8) and compiled into c:\jakarta-tomcat-5.5.9\webapps\liangweb\WEB-INF\classes\chapter35 .
1 package chapter35; 2 3 public class Count { 4 private int count = ; 5 6 /** Return count property */ 7 public int getCount() { 8 return count; 9 } 10 11 /** Increase count */ 12 public void increaseCount() { 13 count++; 14 } 15 } |
The JSP page is named TestBeanScope.jsp (Listing 35.9) and saved in c:\jakarta-tomcat-5.5.9\webapps\liangweb . Run it from the URL http://localhost:8080/liangweb/TestBeanScope.jsp , as shown in Figure 35.6.
1 <!-- TestBeanScope.jsp --> 2 <%@ page import = "chapter35.Count" %> 3 <jsp:useBean id = "count" scope = "application" 4 class = "chapter35.Count" > 5 </jsp:useBean> 6 <html> 7 <head> 8 <title> TestBeanScope </title> 9 </head> 10 <body> 11 <h3> Testing Bean Scope in JSP (Application) </h3> 12 <% count.increaseCount(); %> 13 You are visitor number <%= count.getCount() %><br /> 14 From host: <%= request.getRemoteHost() %> 15 and session: <%= session.getId() %> 16 </body> 17 </html> |
The scope attribute specifies the scope of the bean. scope="application" (line 3) specifies that the bean is alive in the JSP engine and available for all clients to access. The bean can be shared by any client with the directive <jsp:useBean id="count" scope="application" class="Count" > (lines 3 “4). Every client accessing TestBeanScope.jsp causes the count to increase by 1. The first client causes count object to be created, and subsequent access to TestBeanScope uses the same object.
If scope="application" is changed to scope="session" , the scope of the bean is limited to the session from the same browser. The count will increase only if the page is requested from the same browser. If scope="application" is changed to scope="page" , the scope of the bean is limited to the page, and any other page cannot access this bean. The page will always display count 1. If scope="application" is changed to scope="request" , the scope of the bean is limited to the client's request, and any other request on the page will always display count 1.
If the page is destroyed , the count restarts from 0. You can fix the problem by storing the count in a random access file or in a database table. Assume that you store the count in the Count table in a database. The Count table contains an attribute named countValue . The Count class can be modified in Listing 35.10.
1 package chapter35; 2 3 import java.sql.*; 4 5 public class Count { 6 private int count = ; 7 private Statement statement = null ; 8 9 public Count() { 10 initializeJdbc(); 11 } 12 13 /** Return count property */ 14 public int getCount() { 15 try { 16 ResultSet rset = statement.executeQuery 17 ( "select countValue from Count" ); 18 rset. next (); 19 count = rset.getInt( 1 ); 20 } 21 catch (Exception ex) { 22 ex.printStackTrace(); 23 } 24 25 return count; 26 } 27 28 /** Increase count */ 29 public void increaseCount() { 30 count++; 31 try { 32 statement.executeUpdate( 33 "update Count set countValue = " + count); 34 } 35 catch (Exception ex) { 36 ex.printStackTrace(); 37 } 38 } 39 40 /** Initialize database connection */ 41 public void initializeJdbc() { 42 try { 43 Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); 44 45 // Connect to the sample database 46 Connection connection = DriverManager.getConnection( 47 "jdbc:odbc:exampleMDBDataSource" ); 48 49 statement = connection.createStatement(); 50 } 51 catch (Exception ex) { 52 ex.printStackTrace(); 53 } 54 } 55 } |