Home  |  Software Components  |  Examples  |  Books  
   Web Application -> Controller   
The JavaServer (tm) page has five entry fields: present value, future value, interest rate, number of payments, and amortized payment. Enter any four and calculate the fifth.

Web Calculator Application

Part 2: Controller/Dispatcher

This is the application controller. All requests from the client are sent to this module. The controller will validate each request parameter (Present Value, Future Value, exc.), set the values into the TVM bean, and ask the bean to calculate the result. If all goes well, it will then forward the request to the calculator form for display. If there are errors, the request is forwarded to an error page for display instead. This cycle will continue until the viewer leaves the application.

We chose to implemented the controller as a Java Servlet. We could have used a JavaServer Page instead to take advantage of the extensive tag library available to parse parameter strings and help with localization.



Source - CalculatorServlet.java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.math.*;
import java.util.*;
import com.cedarspring.tvm.*;
import com.getobjects.bigdecimal.*;

public class CalculatorServlet extends HttpServlet {
	public void service (HttpServletRequest req, HttpServletResponse res)
		throws ServletException, IOException {
 
		Locale locale = new Locale("en","US");
		Hashtable errors = new Hashtable();

	     /* ------------------------------------------------------------
		* Create an instance of the TVM bean 
		* if one does not already exist in the session and set the locale.  
		* This bean contains all of the financial calculator logic and 
		* stores the state (presentValue, futureValue, interestRate, 
		* etc.) for a particular session. 
		*
		* An instance of the bean will be created for each new session 
		* and placed in the session scope with a name of "tvm". 
		* It is initialized with example values.  The bean will be 
		* available to all 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.  
		*
		* A US English locale is established for all pages in the 
		* session.
		* ---------------------------------------------------------- */
 

		HttpSession session = req.getSession(true);
		TVMu tvm = (TVMu)session.getAttribute("tvm");
		if (tvm == null) {
			tvm = new TVMu();
			tvm.setLocale(locale);
			tvm.setPresentValue(new BigDecimal("200000"));
			tvm.setInterestRate(new BigDecimal("7"));
			tvm.setNumberOfPeriods(new BigDecimal("360"));
			tvm.setPayment(new BigDecimal("-1330.6050"));

			session.setAttribute("tvm", tvm);
			session.setAttribute("javax.servlet.jsp.jstl.fmt.locale", locale);
		}
		


	     /* ---------------------------------------------------------------
		* Validate the request parameters and set them into the TVM bean. 
		* 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 the getParameter(String name) method 
		* of the request object.  
		*
		* We will use a BigDecimalFormat object to parse each parameter 
		* string, to check that it represents a valid decimal number, 
		* and to create a BigDecimal object from it. The BigDecimal 
		* result is set into the TVM bean. The bean may do additional
		* constraint checking.
		*
		* If any error occurs, we will write a parameter name - message
		* pair into a HashTable that can be forwarded to a JSP page for
		* display later.
		*
		* We will treat empty fields a 0.
		*
		* The HTML form values may not be present for the very first
		* request from a session.  We can test for this condition by 
		* checking if the operation field, which must always be
		* present in a valid form, is null. 
		* ------------------------------------------------------------- */

		if (req.getParameter("op") != null) { 
			BigDecimalFormat bdf = new BigDecimalFormat();
			bdf.setLocale(locale);
			String msg = "Value is not numeric:";
			String err = "";
			
			/*-------------------------------------------
			 * Present Value
			 *------------------------------------------- */
			String pv = req.getParameter("presentValue");	
			if (pv.equals("")) {
				pv = "0";
			}

			try {
				tvm.setPresentValue(bdf.parse(pv));
			} catch (Exception e) {
				errors.put("pv", msg);
			}
 			
			/*-------------------------------------------
			 * Future Value
			 *------------------------------------------- */
			String fv = req.getParameter("futureValue");	
			if (fv.equals("")) {
				fv = "0";
			}

			try {
				tvm.setFutureValue(bdf.parse(fv));
			} catch (Exception e) {
				errors.put("fv", msg);
			}
 	
 
 			/*-------------------------------------------
			 * Payment
			 *------------------------------------------- */
			String pmt = req.getParameter("payment");	
			if (pmt.equals("")) {
				pmt = "0";
			}

			try {
				tvm.setPayment(bdf.parse(pmt));
			} catch (Exception e) {
				errors.put("pmt", msg);
			}
 	
	 

		     /*---------------------------------------------------------
			* NumberOfPeriods and InterestRate must meet additional 
			* constraints beyond being a valid number.  For example,
			* InterestRate cannot be negative. The TVM bean will
			* check these constraints when the BigDecimal is set
			* into these properties. It will place a text message in
			* the message property if the constraint is not satisfied
			* rather than throwing an exception. We must check that
			* the message property is empty.
			* ------------------------------------------------------ */

			/*-------------------------------------------
			 * Number Of Periods
			 *------------------------------------------- */
			String n = req.getParameter("numberOfPeriods");
			if (n.equals("")) {
				n = "0";
			}

			try {
				tvm.setNumberOfPeriods(bdf.parse(n));
				err = tvm.getMessage();
			} catch (Exception e) {
				err = msg;
			}
	
			if (!err.equals("")) {
				errors.put("n", err);
				err = "";
				tvm.clearMessage();	
			}


			/*-------------------------------------------
			 * Interest Rate
			 *------------------------------------------- */
			String i = req.getParameter("interestRate");
			if (i.equals("")) {
				i = "0";
			}

			try {
				tvm.setInterestRate(bdf.parse(i));
				err = tvm.getMessage();
			} catch (Exception e) {
				err = msg;
			}
		
			if (!err.equals("")) {
				errors.put("i", err);
				err = "";
				tvm.clearMessage();	
			}


		     /*----------------------------------------------------
			* Perform the calculator command.  The "op" request
			* parameter contains the operation to preform. Send
			* a message to the proper TVM bean method to carry
			* out the calculation and store the result.
			* ------------------------------------------------- */
	
			String op = req.getParameter("op");
			if (op.equals("Present Value")) 
				tvm.computePresentValue();
			else
				if (op.equals("Future Value")) 
					tvm.computeFutureValue();
			else
				if (op.equals("Periods")) 
					tvm.computeNumberOfPeriods();
			else
				if (op.equals("Interest Rate")) 
					tvm.computeInterestRate();
			else 
				tvm.computePayment();

			err = tvm.getMessage();
			if (!err.equals("")) {
				errors.put("cmp", err);
				tvm.clearMessage();
			}
		}
		
	     /*--------------------------------------------------------------
		* Dispatcher.  
		* no errors - forward the request to the calculator form view.
		* errors    - add the error table to the request and forward
		*             it to the error form view.
		* ----------------------------------------------------------- */
		RequestDispatcher rd;
		if (errors.isEmpty()) {	
			rd = getServletContext().getRequestDispatcher("/calculatorForm.jsp");
		} else {
			req.setAttribute("errors",errors);
			rd = getServletContext().getRequestDispatcher("/calculatorErrors.jsp");
		}
		
		rd.forward(req, res);
	}
}
  

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