Often properties are associated with input parameters. Suppose you want to get the value of the input parameter named score and set it to the JavaBeans property named score . You could write the following code:
<% double score = Double.parseDouble( request.getParameter( "score" )); %> <jsp:setProperty name = "beanId" property = "score" value = "<%= score %>" />
This is cumbersome. JSP provides a convenient syntax that can be used to simplify it:
<jsp:setProperty name = "beanId" property = "score" param = "score" />
Instead of using the value attribute, you use the param attribute to name an input parameter. The value of this parameter is set to the property.
Note
Simple type conversion is performed automatically when a bean property is associated with an input parameter. A string input parameter is converted to an appropriate primitive data type or a wrapper class for a primitive type. For example, if the bean property is of the int type, the value of the parameter will be converted to the int type. If the bean property is of the Integer type, the value of the parameter will be converted to the Integer type. |
Often the bean property and the parameter have the same name. You can use the following convenient statement to associate all the bean properties in beanId with the parameters that match the property names :
<jsp:setProperty name = "beanId" property = "*" />
This example uses JavaBeans to simplify Listing 35.4, ComputeLoan1.jsp, by associating the bean properties with the input parameters. The new ComputeLoan.jsp is given in Listing 35.11.
1 <!-- ComputeLoan2.jsp --> 2 <html> 3 <head> 4 <title> ComputeLoan Using the Loan Class </title> 5 </head> 6 <body> 7 <%@ page import = "chapter35.Loan" %> 8 <jsp:useBean id = "loan" class = "chapter35.Loan" 9 scope = "page" ></jsp:useBean> 10 <jsp:setProperty name = "loan" property = "*" /> 11 Loan Amount: <%= loan.getLoanAmount() %> <br /> 12 Annual Interest Rate: <%= loan.getAnnualInterestRate() %><br /> 13 Number of Years : <%= loan.getNumberOfYears() %><br /> 14 <b> Monthly Payment: <%= loan.getMonthlyPayment() %><br /> 15 Total Payment: <%= loan.getTotalPayment() %> <br /></b> 16 </body> 17 </html> |
Line 8
<jsp:useBean id = "loan" class = "chapter35.Loan" scope = "page" > </jsp:useBean>
creates a bean named loan for the Loan class. Line 10
<jsp:setProperty name = "loan" property = "*" />
associates the bean properties loanAmount , annualInteresteRate , and numberOfYears with the input parameter values and performs type conversion automatically.
Lines 11 “13 use the accessor methods of the loan bean to get the loan amount, annual interest rate, and number of years.
This program acts the same as in Listing 35.3 and 35.4, ComputeLoan.jsp and ComputeLoan1.jsp, but the coding is much simplified.
This example creates a JavaBeans component named FactorialBean and uses it to compute the factorial of an input number in a JSP page named FactorialBean.jsp, as shown in Figure 35.7.
Create a JavaBeans component named FactorialBean.java (Listing 35.12) and compile it into c:\jakarta-tomcat-5.5.9\webapps\liangweb\WEB-INF\classes\chapter35 .
1 package chapter35; 2 3 public class FactorialBean { 4 private int number; 5 6 /** Return number property */ 7 public int getNumber() { 8 return number; 9 } 10 11 /** Set number property */ 12 public void setNumber( int newValue) { 13 number = newValue; 14 } 15 16 /** Obtain factorial */ 17 public long getFactorial() { 18 long factorial = 1 ; 19 for ( int i = 1 ; i <= number; i++) 20 factorial *= i; 21 return factorial; 22 } 23 } |
Create FactorialBean.jsp (Listing 35.13) and save it into c:\jakarta-tomcat-5.5.9\webapps\liangweb . Run it from the URL http://localhost:8080/liangweb/FactorialBean.jsp , as shown in Figure 35.7.
1 <!-- FactorialBean.jsp --> 2 <%@ page import = "chapter35.FactorialBean" %> 3 <jsp:useBean id = "factorialBeanId" 4 class = "chapter35.FactorialBean" scope = "page" > 5 </jsp:useBean> 6 <jsp:setProperty name = "factorialBeanId" property = "*" /> 7 <html> 8 <head> 9 <title> 10 FactorialBean 11 </title> 12 </head> 13 <body> 14 <h3> Compute Factorial Using a Bean </h3> 15 <form method = "post" > 16 Enter new value: <input name = "number" /><br /><br /> 17 <input type = "submit" name = "Submit" 18 value = "Compute Factorial" /> 19 <input type = "reset" value = "Reset" /><br /><br /> 20 Factorial of 21 <jsp:getProperty name = "factorialBeanId" 22 property = "number" /> is 23 <%@ page import = "java.text.*" %> 24 <% NumberFormat format = NumberFormat.getNumberInstance(); %> 25 <%= format.format(factorialBeanId.getFactorial()) %> 26 </form> 27 </body> 28 </html> |
The jsp:useBean tag (lines 3 “5) creates a bean factorialBeanId of the FactorialBean class. Line 6 <jsp:setProperty name="factorialBeanId" property="*" /> associates all the bean properties with the input parameters that have the same name. In this case, the bean property number is associated with the input parameter number . When you click the Compute Factorial button, JSP automatically converts the input value for number from string into int and sets it to factorialBean before other statements are executed.
Lines 21 “22 <jsp:getProperty name="factorialBeanId" property="number" /> is equivalent to <%= factorialBeanId.getNumber() %> . The method factorialBeanId.getFactorial() (line 25) returns the factorial for the number in factorialBeanId .
Listing 34.5, TimeForm.java, gives a Java servlet that uses the doGet method to generate an HTML form for the user to specify a locale and time zone (Figure 34.14(a)), and uses the doPost method to display the current time for the specified time zone in the specified locale (Figure 34.14(b)). This section rewrites the servlet using JSP. You have to create two JSP pages, one for displaying the form and the other for displaying the current time.
In the TimeForm.java servlet, arrays allLocale and allTimeZone are the data fields. The doGet and doPost methods both use the arrays. Since the available locales and time zones are used in both pages, it is better to create an object that contains all available locales and time zones. This object can be shared by both pages.
Let us create a JavaBeans component named TimeBean.java (Listing 35.14) and compile it into c:\jakarta-tomcat-5.5.9\webapps\liangweb\WEB-INF\classes\chapter35 . This class simply obtains all the available locales.
1 package chapter35; 2 3 import java.util.*; 4 5 public class TimeBean { 6 private Locale[] allLocale = Locale.getAvailableLocales(); 7 private String[] allTimeZone = TimeZone.getAvailableIDs(); 8 9 public Locale[] getAllLocale() { 10 return allLocale; 11 } 12 13 public String[] getAllTimeZone() { 14 return allTimeZone; 15 } 16 } |
Create DisplayTimeForm.jsp (Listing 35.15) and save it into c:\jakarta-tomcat-5.5.9\webapps\liangweb . This page displays a form just like the one shown in Figure 34.14(a). Line 2 imports the TimeBean class. A bean is created in lines 3 “5 and is used in lines 17, 19, 24, and 26 to return all locales and time zones. The scope of the bean is application (line 4), so the bean can be shared by all sessions of the application.
1 <!-- DisplayTimeForm.jsp --> 2 <%@ page import = "chapter35.TimeBean" %> 3 <jsp:useBean id = "timeBeanId" 4 class = "chapter35.TimeBean" scope = "application" > 5 </jsp:useBean> 6 7 <html> 8 <head> 9 <title> 10 Display Time Form 11 </title> 12 </head> 13 <body> 14 <h3> Choose locale and time zone </h3> 15 <form method = "post" action = " DisplayTime.jsp " > 16 Locale <select size = "1" name = "locale" > 17 <% for (int i = 0; i < timeBeanId.getAllLocale().length ; i++) {%> 18 <option value = "<%= i %>" > 19 <%= timeBeanId.getAllLocale()[i] %> 20 </option> 21 <%}%> 22 </select><br /> 23 Time Zone <select size = "1" name = "timezone" > 24 <% for (int i = 0; i < timeBeanId.getAllTimeZone().length ; i++) {%> 25 <option value = "<%= i %>" > 26 <%= timeBeanId.getAllTimeZone()[i] %> 27 </option> 28 <%}%> 29 </select><br /> 30 <input type = "submit" name = "Submit" 31 value = "Get Time" /> 32 <input type = "reset" value = "Reset" /> 33 </form> 34 </body> 35 </html> |
Create DisplayTime.jsp (Listing 35.16) and save it into c:\jakarta-tomcat-5.5.9\webapps\liangweb . This page is invoked from DisplayTimeForm.jsp to display the time with the specified locale and time zone, just as in Figure 34.14(b).
1 <!-- DisplayTime.jsp --> 2 <%@page pageEncoding = "GB18030" %> 3 <%@ page import = "java.util.*" %> 4 <%@ page import = "java.text.*" %> 5 <%@ page import = "chapter35.TimeBean" %> 6 <jsp:useBean id = "timeBeanId" 7 class = "chapter35.TimeBean" scope = "application" > 8 </jsp:useBean> 9 10 <html> 11 <head> 12 <title> 13 Display Time 14 </title> 15 </head> 16 <body> 17 <h3> Choose locale and time zone </h3> 18 <% 19 out.println( "<html>" ); 20 int localeIndex = Integer.parseInt( 21 request.getParameter( "locale" )); 22 String timeZoneID = request.getParameter( "timezone" ) ; 23 out.println( "<head><title>Current Time</title></head>" ); 24 out.println( "<body>" ); 25 Calendar calendar = 26 new GregorianCalendar( timeBeanId.getAllLocale()[localeIndex] ); 27 TimeZone timeZone = TimeZone.getTimeZone(timeZoneID); 28 DateFormat dateFormat = DateFormat.getDateTimeInstance( 29 DateFormat.FULL, DateFormat.FULL, 30 timeBeanId.getAllLocale()[localeIndex]) ; 31 dateFormat.setTimeZone(timeZone); 32 out.println( "Current time is " + 33 dateFormat.format(calendar.getTime()) + "</p>" ); 34 out.println( "</body></html>" ); 35 %> 36 </body> 37 <html> |
Line 2 sets the character encoding for the page to GB18030 for displaying international characters . By default, it is UTF-8.
Since this page uses the TimeZone class from the java.util package and the DateFormat class from the java.text package, these two packages are imported in lines 3 “4.
Line 5 imports chapter35.TimeBean and creates a bean using the same id as in the preceding page. Since the object is already created in the preceding page, the beanFormId in this page (lines 6 “8) and in the preceding page point to the same object.
Listing 34.11, RegistrationWithHttpSession.java, gives a Java servlet that obtains student information from an HTML form (see Figure 34.17) and displays the information for user confirmation (see Figure 34.18). Once the user confirms it, the servlet stores the data into the database. This section rewrites the servlet using JSP. You will create two JSP pages, one named GetRegistrationData.jsp for displaying the data for user confirmation and the other named StoreData.jsp for storing the data into the database.
Since every session needs to connect to the same database, you should declare a class for connecting to the database and for storing a student to the database. This class named StoreData is given in Listing 35.17. The initializeJdbc method (lines 14 “38) connects to the database and creates a prepared statement for storing a record to the Address table. The storeStudent method (lines 41 “52) executes the prepared statement to store a student record. A Student class that contains the data fields and their get and set methods is shown in Listing 35.18.
1 package chapter35; 2 3 import java.sql.*; 4 5 public class StoreData { 6 // Use a prepared statement to store a student into the database 7 private PreparedStatement pstmt; 8 9 public StoreData() { 10 initializeJdbc(); 11 } 12 13 /** Initialize database connection */ 14 private void initializeJdbc() { 15 try { 16 // Declare driver and connection string 17 String driver = "sun.jdbc.odbc.JdbcOdbcDriver" ; 18 String connectionString = "jdbc:odbc:exampleMDBDataSource" ; 19 20 // Load the Oracle JDBC Thin driver 21 Class.forName(driver); 22 System.out.println( "Driver " + driver + " loaded" ); 23 24 // Connect to the sample database 25 Connection conn = DriverManager.getConnection 26 (connectionString); 27 System.out.println( "Database " + connectionString + 28 " connected" ); 29 30 // Create a Statement 31 pstmt = conn.prepareStatement( "insert into Address " + 32 "(lastName, firstName, mi, telephone, email, street, city, " 33 + "state, zip) values (?, ?, ?, ?, ?, ?, ?, ?, ?)" ); 34 } 35 catch (Exception ex) { 36 System.out.println(ex); 37 } 38 } 39 40 /** Store a student record to the database */ 41 public void storeStudent(Student student) throws SQLException { 42 pstmt.setString( 1 , student.getLastName()); 43 pstmt.setString( 2 , student.getFirstName()); 44 pstmt.setString( 3 , student.getMi()); 45 pstmt.setString( 4 , student.getTelephone()); 46 pstmt.setString( 5 , student.getEmail()); 47 pstmt.setString( 6 , student.getStreet()); 48 pstmt.setString( 7 , student.getCity()); 49 pstmt.setString( 8 , student.getState()); 50 pstmt.setString( 9 , student.getZip()); 51 pstmt.executeUpdate(); 52 } 53 } |
1 package chapter35; 2 3 public class Student { 4 private String firstName; 5 private String mi; 6 private String lastName; 7 private String telephone; 8 private String street; 9 private String city; 10 private String state; 11 private String email; 12 private String zip; 13 14 public String getFirstName() { 15 return this .firstName; 16 } 17 18 public void setFirstName(String firstName) { 19 this .firstName = firstName; 20 } 21 22 public String getMi() { 23 return this .mi; 24 } 25 26 public void setMi(String mi) { 27 this .mi = mi; 28 } 29 30 public String getLastName() { 31 return this .lastName; 32 } 33 34 public void setLastName(String lastName) { 35 this .lastName = lastName; 36 } 37 38 public String getTelephone() { 39 return this .telephone; 40 } 41 42 public void setTelephone(String telephone) { 43 this .telephone = telephone; 44 } 45 46 public String getEmail() { 47 return this .email; 48 } 49 50 public void setEmail(String email) { 51 this .email = email; 52 } 53 54 public String getStreet() { 55 return this .street; 56 } 57 58 public void setStreet(String street) { 59 this .street = street; 60 } 61 62 public String getCity() { 63 return this .city; 64 } 65 66 public void setCity(String city) { 67 this .city = city; 68 } 69 70 public String getState() { 71 return this .state; 72 } 73 74 public void setState(String state) { 75 this .state = state; 76 } 77 78 public String getZip() { 79 return this .zip; 80 } 81 82 public void setZip(String zip) { 83 this .zip = zip; 84 } 85 } |
The HTML file that displays the form is identical to Registration.html in Listing 34.8 except that the action is replaced by
http: //localhost:8080/liangweb/GetRegistrationData.jsp
GetRegistrationData.jsp, which obtains the data from the form, is shown in Listing 35.19. A bean is created in lines 3 “4. Line 5 obtains the property values from the form. This is a shorthand notation. Note that the parameter names and the property names must be the same to use this notation.
1 <!-- GetRegistrationData.jsp --> 2 <%@ page import = "chapter35.Student" %> 3 <jsp:useBean id = "studentId" 4 class = "chapter35.Student" scope = "session" ></jsp:useBean> 5 <jsp:setProperty name = "studentId" property = "*" /> 6 7 <html> 8 <body> 9 <h1> Registration Using JSP </h1> 10 11 <% 12 if (studentId.getLastName() == null 13 studentId.getFirstName() == null ) { 14 out.println( "Last Name and First Name are required" ); 15 return ; // End the method 16 } 17 %> 18 19 <p> You entered the following data </p> 20 <p> Last name: <%= studentId.getLastName() %></p> 21 <p> First name: <%= studentId.getFirstName() %></p> 22 <p> MI: <%= studentId.getMi() %></p> 23 <p> Telephone: <%= studentId.getTelephone() %></p> 24 <p> Email: <%= studentId.getEmail() %></p> 25 <p> Address: <%= studentId.getStreet() %></p> 26 <p> City: <%= studentId.getCity() %></p> 27 <p> State: <%= studentId.getState() %></p> 28 <p> Zip: <%= studentId.getZip() %></p> 29 30 <!-- Set the action for processing the answers --> 31 <form method = "post" action = "/liangweb/StoreStudent.jsp" > 32 <input type = "submit" value = "Confirm" > 33 </form> 34 </body> 35 </html> |
GetRegistrationData.jsp invokes StoreStudent.jsp (Listing 35.20) when the user clicks the Confirm button. The same studentId is shared with the preceding page within the scope of the same session in lines 3 “4. A bean for StoreData is created in lines 5 “6 with the scope of application.
1 <!-- StoreStudent.jsp --> 2 <%@ page import = "chapter35.Student" %> 3 <jsp:useBean id = "studentId" class = "chapter35.Student" 4 scope = "session" ></jsp:useBean> 5 <jsp:useBean id = "storeDataId" class = "chapter35.StoreData" 6 scope = "application" ></jsp:useBean> 7 8 <html> 9 <body> 10 <% 11 storeDataId.storeStudent(studentId); 12 13 out.println(studentId.getFirstName() + " " + 14 studentId.getLastName() + 15 " is now registered in the database" ); 16 out.close(); // Close stream 17 %> 18 </body> 19 </html> |
Note
The scope for studentId is session, but the scope for storeDataId is application . Why? GetRegistrationData.jsp obtains student information, and StoreData.jsp stores the information in the same session. So the session scope is appropriate for studentId . All the sessions access the same database and use the same prepared statement to store data. With the application scope for storeDataId , the bean for StoreData needs to be created just once. |
Note
The storeStudent method in line 11 may throw a java.sql.SQLException . In JSP, you can omit the try-block for checked exceptions . In case of an exception, JSP displays an error page. |