Home  |  Software Components  |  Examples  |  Books  
Note: This is an old example that has been kept so that bookmarks are not broken. It was created about a year before the Java Standard Tag Library (JSTL) was released. We recommend that you look at the new JSTL first since it makes many of these tags obsolete. A newer example uses JSTL and an MVC design to accomplish the same result.

 
JavaServer PagesTM (JSP) technology provides a way to quickly build dynamic web pages from custom tags and reusable components. The pages can be accessed by a wide variety of browsers, even older versions that are not Java-enabled or have that feature turned off. All of the application logic is contained on the server, so the browser only needs to display standard HTML forms. Learn more at Sun's JSP site.

Here is a JSP application for a simple financial calculator that uses our TVM bean. The application will display a dynamic calculator like the one shown in the image on the right when it is used with a web server that supports servlets/JSP.

Source|Deployment|Design
The JavaServer (tm) page has seven entry fields: beginning and ending balance, interest rate, number of payments, payments per year, and compounding per year.  The payment per period is displayed when the calculate button is pressed.
 

mortgage.jsp

<%-- -----------------------------------------------------------
The entire application is contained in a single JavaServer Page 
to make this simple example easier to understand.  For more 
substantial applications, you should consider the 
Model-View-Controller architecture which separates the control,
business logic, and presentation into separate modules.

The Page Directive sets general attributes for the entire page.

  language. Java will be used as the scripting language. 

  import. Classes in these packages can be referred to by 
  their unqualified class names.

  errorPage The mortgageErrors.jsp page will be displayed
  if any uncaught errors occur while processing this page.

  isThreadSafe. This page can be used for multiple, 
  simultaneous requests. The variable data for each session will
  be stored in a separate instance of a TVM bean.

----------------------------------------------------------- --%>
<%@ page 
	language="java" 
	import="com.cedarspring.tvm.*,java.math.*" 
	errorPage="mortgageErrors.jsp"
	isThreadSafe="true" 
%> 


<%-- ------------------------------------------------------------
This custom tag library contains actions to set and format
BigDecimal numbers and other actions specific to the TVM bean.

  uri an absolute URI that identifies the tag library.  The
       server will try to match this identifier to a taglib-uri 
       entry in the web.xml file and then use the corresponding 
       taglib-location to find the library jar.

  prefix a short XML namespace identifier used as a prefix to
       all tags from this library.  For example: <go:press />
------------------------------------------------------------- --%>
<%@ taglib
	uri="http://www.getobjects.com/taglibs/go"
	prefix="go"
%>

<%-- ------------------------------------------------------------
Create an instance of the TVM bean. This bean contains all of 
the financial calculator logic and stores the state (presentValue,
futureValue, interestRate, etc.) for a particular session. 

Id. An identifier for the bean that will be used in other
tags and scripts within this page.

class. The fully qualified class name of the TVM bean.

scope. Session.  An instance of the bean will be created 
for each new session and placed in the session scope. The bean 
will be available to this page and to all other pages that 
participate in the session. Any property  values that are set 
will persist in the bean for the remainder of the session unless
they are explicitly changed. This will allow the user to set 
optional properties (rounding, precision, etc.) once at the 
beginning of a session and then enter just the six main 
properties for all subsequent requests.  However, using 
session scope rather than request or page can cause problems.

The bean is initialized to example values in the body of
the tag between <jsp:useBean> and </jsp:usebean>.  Actions in the
body of useBean are only performed when a new bean is created -
in this example, at the beginning of each new session. 

-------------------------------------------------------------- --%>
<jsp:useBean 
	id="tvm" 
	class="com.cedarspring.tvm.TVMu" 
	scope="session">

	<go:setDecimalProperty 
		name="tvm" 
		property="presentValue" 
		value="105000" />

	<go:setDecimalProperty 
		name="tvm" 
		property="interestRate" 
		value="7.3" />

	<go:setDecimalProperty 
		name="tvm" 
		property="numberOfPeriods" 
		value="360" />
</jsp:useBean>


<%-- --------------------------------------------------------
Set the TVM properties from the request object. The request
object, in addition to other useful info, contains all the
values from our HTML form as sets of name-value pairs. They
can be retrieved with either the getParameter(String name) 
method of the request object or with the go:setDecimalProperty 
tag.

The HTML form values will not be present for the very first
request from a session.  We can test for this condition by 
checking if any of the parameters is null. 

--------------------------------------------------------- --%>

<% if (request.getParameter("presentValue") != null) { %>
	<go:setDecimalProperty name="tvm" property="presentValue" />
	<go:setDecimalProperty name="tvm" property="futureValue" />
	<go:setDecimalProperty name="tvm" property="interestRate" />
	<go:setDecimalProperty name="tvm" property="numberOfPeriods" />
	<jsp:setProperty  name="tvm" property="paymentsPerYear" />
	<jsp:setProperty name="tvm" property="compoundingPerYear" />
<% }; %>


<%-- -----------------------------------------------------
Write the HTML to draw the calculator form.  We will
retrieve each value from the TVM bean using the
go:getDecimalProperty tag and display it in the HTML form 
field.
------------------------------------------------------ --%>
<html>
<head>
<title>Mortgage Payment Calculator</title>
</head>
<body bgcolor="white">

<div align="center"><center>

<%-- -----------------------------------------------------
When the submit button is clicked, the request will be posted 
back to this page.
------------------------------------------------------ --%>
<form method="post" action="mortgage.jsp">
<p> 
<h2>Mortgage Payment Calculator</h2>
<table border="0" cellpadding="5" cellspacing="0">
  <tr>
  <td><b>Beginning Balance:</b></td>
  <td> <input 
		name="presentValue" 
		type="text" size="20" 
		value='<go:getDecimalProperty 
				name="tvm" 
				property="presentValue"
				scale="2" />'>
  </td>
  </tr>

  <tr>
  <td><b>Ending Balance:</b></td>
  <td><input 
		name="futureValue" 
		type="text" size="20" 
		value='<go:getDecimalProperty 
				name="tvm" 
				property="futureValue" 
				scale="2" />'>
  </td>
  </tr>

  <tr>
  <td><b>Interest Rate:</b></td>
  <td><input 
		name="interestRate" 
		type="text" size="5" 
		value='<go:getDecimalProperty 
				name="tvm" 
				property="interestRate"
				scale="4"
				round="False"/>'>
  </td>
  </tr>

  <tr>
  <td><b>Number Of Periods:</b></td>
  <td><input 
		name="numberOfPeriods" 
		type="text" size="5" 
		value='<go:getDecimalProperty 
				name="tvm" 
				property="numberOfPeriods"
				scale="0"
				round="False" />'>
  </td>
  </tr>

  <tr>
  <td><b>Payments Per year:</b></td>
  <td><input 
		name="paymentsPerYear" 
		type="text" size="5" 	
		value='<jsp:getProperty 
				name="tvm" 
				property="paymentsPerYear"/>'>
  </td>
  </tr>

  <tr>
  <td><b>Compounding Per Year:</b></td>
  <td><input 
		name="compoundingPerYear" 
		type="text" size="5" 
		value='<jsp:getProperty 
				name="tvm" 
				property="compoundingPerYear"/>'>
  </td>
  </tr>

  <tr> 
  <td colspan="2"><hr></td>
  </tr>

</table>
<p>
<input type="submit" value="Calculate Payment">
<form>

<p>

<%-- ----------------------------------------------------------
Compute the payment
----------------------------------------------------------  --%>
<go:press name="tvm" button="computePayment" />


<%-- -----------------------------------------------------------
The TVM bean does not throw exceptions when errors occur (for 
example, number of periods is 0) to make it easier to wire the 
bean in visual builder tools. When an error occurs, it fires an 
exception and sets the message property.  If the message property 
contains an error string after all the properties have been set, 
we will forward the request to the error page for further analysis.

The error messages are in US English by default.  You can add
additional message files for other languages or for industry
specific terms.  
------------------------------------------------------------ --%>
<p>
<% if (!tvm.getMessage().equals("")) { %>
	<jsp:forward page="mortgageErrors.jsp" />
<% } %>

<br>
<big>Your payment will be 
  <go:getDecimalProperty name="tvm" property="payment" scale="2" />
<big>

</center></div>
</body>
</html>



Web Application Deployment Descriptor

After the JSP pages have been written, create a Web Application Deployment Descriptor that describes the application to the server. The descriptor is an XML document that is always named web.xml. For this simple application, only display-name and taglib entries are needed.

Web.xml



<!DOCTYPE web-app
  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
  "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<web-app>
  
  <display-name>Calculator</display-Name>

  <taglib>
     <taglib-uri>http://www.getobjects.com/taglibs/go</taglib-uri>
     <taglib-location>/WEB-INF/lib/go.jar</taglib-location>
  </taglib>

</web-app>

 

Each of the JSP pages (mortgage.jsp and mortgageErrors.jsp) contains a taglib directive with a uri attribute that uniquely identifies the GO custom tag library:

<%@ taglib
	uri="http://www.getobjects.com/taglibs/go"
	prefix="go"
%>
The server will try to match this identifier to a taglib-uri entry in the web.xml file and then use the corresponding taglib-location to find the library jar. This indirect method gives us more flexibility should the tag library name or location change. However, the taglib directive in the JSP page could have pointed directly to the taglib jar. In that case, this mapping entry would not be necessary.

 


Web ARchive (WAR)

Next, create a directory structure that conforms to the WAR format and place all of the application resources within it. The name of the root directory (calculator) will become the name of the application. All servers that conform to Servlet API Specification, version 2.2 should accept this format. It combines all the resources that the server needs to run an application into one convenient package that can be dropped onto the server. There is no need to set a classpath or do any other configuration.

The application resources consist of the two JSP pages, the TVM bean jar, the GO custom tag library jar, and the web.xml application descriptor. Arrange them in the root directory and sub-directories as follows:

calculator/
    mortgage.jsp
    mortgageErrors.jsp
    options.jsp

  META-INF/
      web.xml

    classes/
    lib/
        TVM.jar
        go.jar


Deployment

Move the entire application directory structure (sometimes called an unpacked web archive) to the server. For a Tomcat server, it should be moved under the webapps/ subdirectory, but the location will vary for others. Then execute the application from any browser with the URL:

http://mycompany.com/calculator/mortgage.jsp

After the application has been tested, pack the directory into a Web ARchive (.war) file to make it more portable. A WAR file is just a JAR file with a .war extention that contains a directory hierarchy like the unpacked archive structure that was just created. Change the default to the calculator directory and execute the jar utility:

jar -cvf calculator.war .

This includes all the files and sub-directories under the calculator directory, but not the directory itself.

Application Design

This application will calculate a fixed payment of interest and principal that will exactly pay off the loan in the number of periods specified. The user must enter these variables on an HTML form:
  • Loan amount (beginning balance)
  • Ending balance (normally 0)
  • Number of payment periods
  • Number of payments and compounding periods per year
  • Interest rate
All of the logic needed to calculate the payment is contained in the TVM java bean. The user will enter the six variables into the HTML form and then click the "Calculate Payment" button (submit). The Action attribute of the form will cause the request to be sent to the mortgage.jsp page again. The application only needs to set the form fields into the bean, invoke the computePayment method, and then display the result.

Bean Scope

The TVM bean could be placed in the session, request, or page scope. It has been placed in the session scope so the user can set optional properties (rounding, precision, etc.) once at the beginning of a session and then enter just the six main properties for all subsequent requests. However, using session scope rather than request or page can cause problems:
  • The bean for each session will persist until the session is terminated which may be 30 minutes after the users last request. If the bean were placed in the request scope instead, the object could be destroyed as soon as the request terminated. There would be fewer objects on the server which could be significant if there are a large number of users on the site.
     
  • A session can have more than one simultaneous request. This can occur if a second window is opened on a browser (ctrl + N on IE or Netscape) or if requests originate from separate frames of a single HTML page. Then the two requests would access the same session bean and may interfere with one another.

JSP Pages

The application is divided into 3 JSP pages:
  • mortgage.jsp
    This is the main page that contains an HTML form for entering the six fields of the mortgage problem, a submit button, and a space to display the payment. The first time this page is accessed in a particular session, and when the user returns to this page after setting options, the six fields will not exist in the request since the page is called directly from a link, not through the submit mechanism of a form. In that case, the page will just use the properties that are already set into the bean. In all other cases the page will set the corresponding values from the request into the bean properities using setDecimalProperty tags. In either case, the page will then invoke the bean's computePayment method by means of the press tag, and then display the result with the getDecimalProperty tag.

    After the set property phase and the computePayment phase, the page checks the bean's message property. If An error occurred, the request is forwarded to mortgageErrors.jsp for error analysis and display.
     

  • options.jsp (not shown)
    This page contains an HTML form for entering the option fields, a submit button, and a link back to the mortgage.jsp page. The optional properties set by this page will remain in the bean for the remainder of the session and will be used in all subsequent requests from mortgage.jsp.
     
  • mortgageErrors.jsp
    This page is executed if an untrapped exception occcurs anywhere in the mortgage.jsp page or if the request is forwarded to it for error analysis. It will try to set each property in the request and write any error message in red over each form field that contains an error. It will also inform the user of a compute payment error. The response page looks identical to mortgage.jsp, so the user can just correct those fields that contain errors and resubmit the request to mortgage.jsp by clicking the Calculate Payment (submit) button.
     

Copyright ©1998-2004 GetObjects.com  All Rights Reserved
Privacy | Legal & Terms of Use | Trademarks | Feedback | About