Section 18.7. Designing a BudgetPro Servlet


18.7. Designing a BudgetPro Servlet

When designing a servlet, there are many different patterns to follow. We can't hope to cover all the approaches that can be used for effective servlet programming. What we hope to do is show you our previous BudgetPro GUI application rewritten as a servlet, so that you can see the mechanics of a working servlet application. From this, you can become accustomed to the mechanics of a servlet so that you'll feel comfortable with other approaches, too. All servlets need to use these basic mechanisms.

Our BudgetPro GUI application was started from the command line, with a name for the budget and a total dollar amount. We'll use a static HTML page with a form for supplying that information. That will invoke our servlet. The servlet will use HTML pages analogous to the windows we used in our GUIthere will be a main screen that shows the current account listing its subaccounts, and there will also be a screen for creating new subaccounts.

One nice feature of HTML-based Web applications is that you can use hyperlinks as a way to both select something and take an action on it. We'll use that feature in lieu of a View Subaccount button. Instead of selecting a subaccount and then pressing View Subaccount, the user will only have to click on the name of the subaccount. As a hyperlink, it will make the request to the servlet to view that subaccount.

We will still use a button to send us to the screen for creating the subaccounts. We could have used a hyperlink, but this makes the browser page look a bit more like the GUI version.

18.7.1. Prototype

When designing servlets, it's handy to use static HTML pages as a prototype for the work to be done. You can mock up the various screens using HTML, simulate interactions by using hyperlinks to move between the screens, and get a feel for what the screens and interactions will look like.

Such a prototype also serves as a "runnable" specification. It can sometimes be easier to show the action than to describe it with words. And if you take care when you are building these static HTML pages, most of the HTML can be reused directly in the final product. (This will be even more true when we get to JSP.)

18.7.2. Design

Let's review what we need our servlet application to do for us. Given an account name and the initial dollar amount, we need to:

  • Create a top-level account with that amount of dollars

  • Display the current account and its total and remaining dollars, along with a list of its subaccounts, if any

  • Create subaccounts, specifying a name and dollar amount

  • Make a selected subaccount be the current one, displayed as above

After each or any of these actions, the servlet has to spit out the HTML page for the user to view. If the user wants to create a subaccount, then the servlet produces a form page for entering the name and dollar amount for the subaccount. When the user presses a Create button on that page, the browser tells the servlet (via the form data) that the servlet should create the subaccount and redisplay the current account with this new subaccount added to its list.

Tip

It may help to think of the servlet as a two-step process, with a current and future perspective. The first step is the action that the servlet must perform based on the supplied parameters (e.g., create a new account). The second step is the creation of the page allowing the user to take the next (future) action. That page reflects the state of things after the parameter-driven action has occurred. In our example, that means showing the list of subaccounts including the one that we just created.


Let's spell out in more detail what our interactions with the servlet will be, and describe what output we expect for each of those inputs. We will create a keyword to tell the servlet what function we want it to perform; we'll call the parameter func. We will sometimes need two other parameters: name and dollars.

Table 18.1 shows our design as a compact reference.

Table 18.1. BudgetPro servlet actions

func parameter

Other params

Action

Next screen

begin

name, dollars

Create a top-level account, save in the session.

main

mkacct

none

none

subacct

cancel

none

Get account from session.

main

create

name, dollars

Get account from session; create subaccount.

main

cd

name

Get account from session, look up subaccount by name, save as current in session.

main

back

none

Get account from session, get parent from account, save as current in session.

main


The code for our servlet is at http://www.javalinuxbook.com/. Let's look at some of the key parts of the servlet in more detail. We'll look at: 1) reading the parameters, 2) the core business logic of the servlet, as described in Table 18.1, and 3) how we create and output the HTML.

The parsing of the parameters is very straightforward. The request parameter, part of the signature of the doGet() and doPost() methods, can be used to retrieve the parameters we need:

 String act = request.getParameter("func"); String name = request.getParameter("name"); String dollars = request.getParameter("dollars"); 

Notice that we always ask for all three parameters, even though we will often use only one (act). Once we have the requested function in act, it's just a matter of if-then-else-ing our way through the possible values and taking the appropriate actions. We store, or retrieve, the current account in the session manager, thereby providing continuity between browser requests (Example 18.2).

The output is the page to send back to the browser. We create that page as an object, either an AccountView or a SubPage. The HttpServletResponse provides us with an output channel on which to write.

 java.io.PrintWriter out = response.getWriter(); if (nextPage != null) {     response.setContentType("text/html");     out.println(nextPage.toString()); } 

Example 18.2. Implementing the BudgetPro servlet actions
 if ("begin".equals(act)) {     Account top = new Account(name, theUser, dollars);     session.setAttribute("top", top);     session.setAttribute("current", top);     nextPage = new AccountView(top); } else if ("mkacct".equals(act)) {     // show the subaccount creation page     nextPage = new SubPage(null); } else if ("cancel".equals(act)) {     Account current = (Account) session.getAttribute("current");     nextPage = new AccountView(current); } else if ("create".equals(act)) {     Account current = (Account) session.getAttribute("current");     try {         current.createSub(name, dollars);         nextPage = new AccountView(current);     } catch (NumberFormatException nfe) {         // show the subaccount creation page (with error message)         nextPage = new SubPage("Bad number format");     } } else if ("cd".equals(act)) {     Account current = (Account) session.getAttribute("current");     Account nextAcct = current.getSub(name);     session.setAttribute("current", nextAcct);     nextPage = new AccountView(nextAcct); } else if ("back".equals(act)) {     Account current = (Account) session.getAttribute("current");     Account nextAcct = current.getParent();     session.setAttribute("current", nextAcct);     nextPage = new AccountView(nextAcct); } else {     log("Unknown func=["+act+"]");     response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); } 

The way that we construct the output, it will all get sent back to the user in one fell swoop. That's fine for relatively short pages with rapid response time. If response time is a major concern and you are sending large quantities of data, you may want to change things a bit. Instead of building up the output in a StringBuffer and then getting it all back with a toString() call, you could take each of our append() calls and make them individual out.println() calls, to send each snippet of HTML separately. The output can be flushed explicitly, too, using

 response.flushBuffer(); 

You might do such a call just before beginning a database operation, or place such calls at strategic points through your output.



    Java Application Development with Linux
    Java Application Development on Linux
    ISBN: 013143697X
    EAN: 2147483647
    Year: 2004
    Pages: 292

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net