New to Java? We'll help you get started with our revised beginner's tutorial, or our free online textbook.


Get the latest Java books
h t t p : / /w w w . j a v a c o f f e e b r e a k . c o m /

Java Coffee Break

Menu



Learning Java

Articles
Author Profiles
Lessons
FAQ's
Books
Newsletter
Tutorials
Talk Java!

Using Java

Applets
JavaBeans
Servlets
Resources
Discuss Java


Looking for Java resources? Check out the Java Coffee Break directory!

Professional JSP Excerpt
Part Two : The "Page-Centric" Approach

We start by looking at architectures based on the page-centric or client-server approach. We will look at the page-view and page-view with bean architectures.

Applications built using a client-server approach have been around for some time; they consist of one or more application programs running on client machines, and connecting to a server-based application to work. (A good example would be a PowerBuilder or Oracle Forms based system.) CGIs and pre-Servlet applications were generally based on this simple 2-tier model, and with the introduction of Servlets, 2-tier applications could also be created in Java.

This model allows JSPs or Servlets direct access to some resource like a database or legacy application to service a client's request: the early JSP specifications termed this a "Model 1" programming approach. The JSP page is where the incoming request is intercepted processed, and the response sent back to the client; JSPs only differed from Servlets in this scenario by providing cleaner code, and separating code from the content by placing data access in beans.

  This is illustrated in the figure below.

 

The advantage of such an approach is that it is simple to program, and allows the page author to generate dynamic content easily, based upon the request and the state of the resources.

However this architecture does not scale up well for a large number of simultaneous clients since there would be a significant amount of request processing to be performed, and each request must establish or share a potentially scarce/expensive connection to the resource in question. (A good example would be JDBC connections in servlets or JSPs and the need for connection pools.)

Indiscriminate usage of this architecture usually leads to a significant amount of Java code embedded within the JSP page. This may not seem to be much of a problem for Java developers but it is certainly an issue if the JSP pages are maintained by designers: the code tends to get in the designer's way, and you run the risk of your code becoming corrupted when others are tweaking the look and feel.

Of course, it is not necessary to use JSPs, to separate code and presentation in servlets: the use of templates is popular. There are a lot of toolkits that facilitate this, such as 

Page-View

This basic architecture involves direct request invocations to a server page with embedded Java code, and markup tags which dynamically generate output for substitution within the HTML. 

This approach has many benefits. It is very easy to get started and is a low-overhead approach from a development standpoint. All of the Java code may be embedded within the HTML, so changes are confined to a limited area, reducing complexity. The figure below shows the architecture visually.

The big trade-off here is in the level of sophistication. As the scale of the system grows, some limitations of this approach surface, such as including too much business logic in the page instead of factoring forward to a mediating Servlet, or factoring back to a worker bean. As we discussed earlier, utilizing a Servlet and helper beans allow us to separate developer roles more cleanly, and improves the potential for code reuse. Let's start with a fairly simple example JSP page that follows this model, handling requests directly and including all the Java code within the JSP source page. 

We begin with a basic description of the example application. All the examples in this chapter use the JSWDK version 1.0.1, using the default web application directory structure for simplicity. Thus, the JSP and HTML source are under the <jswdk-root>/examples/jsp/ subdirectory and the Servlet (see later) is under <jswdk-root>/examples/WEB-INF/servlets.


The user interface is shown below:

 

The HTML code for this page, BabyGame1.html, is stored in <jswdk-root>/examples/jsp/pageview/ and includes a form that prompts a user for selections. The user is asked to make some guesses about the statistics of a baby to be born in the near future. The HTML code is as follows: 

<html>
<head>
<title>Baby Game</title>
</head>

<body bgcolor="#FFFFFF">
<form method="post" action="BabyGame1.jsp" name="">
<center>
<h3>Baby Game</h3></center>

<center>
<br>

<table BORDER COLS=5 WIDTH="75%" >
<caption>Please enter your own name:
<input type="text" name="guesser"></caption>

<tr>

<td>
<br><input type="radio" name="gender" value="Female" checked>Female
<p><input type="radio" name="gender" value="Male">Male
<p></td>
<td><font size=-1>Please choose a date:</font>
<p>Month: <select name="month">
<option value="January">January</option>
<option value="February">February</option>


 

...

<option value="December">December</option>
<br></select>
<p>Day: <select name="day">
<option value="1">1</option>
<option value="2">2</option>

...

<option value="31">31</option>
<br></select>
<p>&nbsp;</td>
<td><font size=-1>Please choose a weight:</font>
<p>Pounds: <select name="pounds">
<option value="5">5</option>
<option value="6">6</option>
...

<option value="12">12</option>
<br></select>
<p>Ounces: <select name="ounces">
<option value="1">1</option>
<option value="2">2</option>
...

<option value="15">15</option>
<br></select>
<p>&nbsp;</td>
<td><font size=-1>Please choose a length:</font>
<p>Inches: <select name="length">
<option value="14">14</option>
<option value="15">15</option>

...

<option value="25">25</option>

</select><p>&nbsp;<p>&nbsp;<p>&nbsp;</td>
</tr>
</table>
</center>
<br>&nbsp;
<center>
<p><input type="submit" name="submit" value="Make Guess">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<input type="reset" name="reset" value="Reset">
</center>

<br></form>
</body>
</html>

  This HTML form will POST the choices to our JSP, which is shown in source form below (BabyGame1.jsp, stored in directory <jswdk-root>/examples/jsp/pageview/). These choices are then stored and displayed by our simple JSP, which has handled the request directly.

The resulting display looks like this:

 

The first part of BabyGame1.jsp is responsible for extracting the values from each of the request parameters and populating the state of the JSP. The name of the individual making the guess is contained in a request parameter called guesser. Each of the statistics about the baby is stored in a request parameter with an intuitive name, such as gender, length, etc. 

<HTML>

<HEAD><TITLE>Baby Game - Your Guesses</TITLE></HEAD>

<BODY bgcolor=FFFFFF>

<%@ page language="java" import="java.util.*,java.io.*" buffer="8k" %>

 

<%

   String guesser = request.getParameter("guesser");

 

   String gender = request.getParameter("gender");

 

   String pounds = request.getParameter("pounds");

   String ounces = request.getParameter("ounces");

   String month = request.getParameter("month");

   String day = request.getParameter("day");

 

   String length = request.getParameter("length");

 

After this task is complete, there is a validation check on the data. If the validation is unsuccessful, then the JSP completes its processing by sending the user an appropriate message:

 

   if(guesser == null || gender == null || pounds == null || ounces == null

      || month == null || day == null || length == null)

{ %>

<br> There where some choices that were not selected.<br><br>

Sorry, but you must complete all selections to play.<br>

<font size=-1>(Please hit the browser 'back' button to continue)</font><br>

<%}

 Otherwise, upon successful validation of the request parameters, the data is stored to disk and a table is generated using the JSP state, which corresponds to the user's guesses. The guesses are stored within a java.util.Properties object, which, for example purposes, is flattened to a text file in the root directory of the JSP run time engine, in this case the JSWDK root directory. The name of the text file corresponds to the name of the guesser, which was provided in the HTML form. One could easily imagine an even more basic example where the data was merely displayed but not stored. Such an example would differ only in that the storage code in BabyGame1.jsp would be omitted: 

else

{

//Store guess info and display to user

Properties p = new Properties();

p.put("guesser", guesser);

p.put("gender", gender);

p.put("pounds", pounds);

p.put("ounces", ounces);

p.put("month", month);

p.put("day", day);

p.put("length", length);

 

FileOutputStream outer = new FileOutputStream(guesser);

p.save(outer, "Baby Game -- "+guesser+"'s guesses");

outer.flush();

outer.close();

 

%>

 

<br>

<%= guesser %>, your choices have been stored.<br>  Here they are:<br>

<table BORDER COLS=5 WIDTH="75%" >

<caption></caption>

 

<tr>

 

<td> <%= gender %>

</td>

<td>

<%= pounds %> lbs <%= ounces %> oz

</td>

<td>

<%= month %> <%= day %>

</td>

<td>

<%= length %> inches

</td>

 

</tr>

</table>

 

<br>

<%}

%>

</BODY>

</HTML>

This JSP certainly was easy to build and is well suited to handling such simple needs. It is getting quite cluttered with Java code, though, and its processing requirements are extremely simplistic. More sophisticated business rules and data access code would require much more Java within the JSP and the source would become unwieldy quickly as it grows. Additionally, we are limited to mostly "cut-and-paste" reuse, which means duplicate code and a more error-prone environment that is harder to maintain and debug.

In order to reduce the clutter of the current example and to provide a cleaner environment for future growth, we will look at another 'Page-Centric' architecture called 'Page-View with Bean' in the next section.

Page-View with Bean

This pattern is used when the Page-View architecture becomes too cluttered with business-related code and data access code. The Baby Game example now evolves into a more sophisticated design, as shown in the figure below.

The modified JSP source page, <jswdk-root>/examples/jsp/pageviewwithbean/
BabyGame1.jsp
, is shown below, followed by the worker bean that works in tandem with the modified JSP in order to process the request. The HTML for the initial game interface remains unchanged. The resulting display to the user from the JSP is basically unchanged from that of the previous 'Page-View' example:

<HTML>

<HEAD><TITLE>Baby Game - Your Guesses</TITLE></HEAD>

<BODY bgcolor=FFFFFF>

<%@ page language="java" buffer="8k" %>

<jsp:useBean id="worker1" class="examples.pageviewwithbean.BabyGameWorker1"

 scope="request" />

 

<%-- Populate the JavaBean properties from the Request parameters. --%>

<%-- The semantics of the '*' wildcard is to copy all similarly-named --%>

<%-- Request parameters into worker1 properties. --%>

<jsp:setProperty name="worker1" property="*" />

 

<%

   if(worker1.getGuesser == null || worker1.getGender() == null ||

      worker1.getPounds() == null || worker1.getOunces() == null ||

      worker1.getMonth() == null || worker1.getDay() == null ||

      worker1.getLength() == null)

{ %>

<br> There where some choices that were not selected.<br><br>

Sorry, but you must complete all selections to play.<br>

<font size=-1>(Please hit the browser 'back' button to continue)</font><br>

<%}

else

{

worker1.store();

%>

<br>

<jsp:getProperty name="worker1" property="guesser" />, your choices have

been stored.<br>  Here they are:<br>

<table BORDER COLS=5 WIDTH="75%" >

<caption></caption>

 

<tr>

 

<td> <jsp:getProperty name="worker1" property="gender" />

</td>

<td>

<jsp:getProperty name="worker1" property="pounds" />  lbs

<jsp:getProperty name="worker1" property="ounces" />  oz

</td>

<td>

<jsp:getProperty name="worker1" property="month" />

<jsp:getProperty name="worker1" property="day" />

</td>

<td>

<jsp:getProperty name="worker1" property="length" />  inches

</td>

 

</tr>

</table>

<br>

<%}

%>

</BODY>

</HTML>

The source for the worker bean, BabyGameWorker1, is as follows:

package examples;

 

import java.io.*;

import java.util.Properties;

 

public class BabyGameWorker1

{

  private Properties p = new Properties();

 

  public String getGuesser() {

    return(String)p.get("guesser");

  }

 

  public void setGuesser(String aString) {

    p.put("guesser", aString);

  }

 

  // And similar "get" and "set" methods for Gender, Pounds, Ounces, Month,

  // Day, Length, and File.

 

  public Properties getProperties() {

    return p;

  }

  public void store() throws IOException {

    FileOutputStream outer = new FileOutputStream((String)p.get("guesser"));

    p.save(outer, "Baby Game -- "+p.get("guesser")+"'s guesses");

    outer.flush();

    outer.close();

 

  }

 

}

We see in these two listings that the Java code representing the business logic and simple data storage implementation has migrated from the JSP to the JavaBean worker. This refactoring leaves a much cleaner JSP with limited Java code, which can be comfortably owned by an individual in a web-production role, since it encapsulates mostly markup tags.

Additionally, a less technical individual could be provided with a property sheet for the JavaBean workers, providing a listing of properties that are made available to the JSP page by the particular worker bean, and the desired property may simply be plugged into the JSP getProperty action via the markup tag in order to obtain the attribute value. An example of a potential property sheet is shown below. Additionally, once a convention and format were agreed upon, an automated tool could be created to interrogate all JavaBeans of interest and generate property sheets automatically.

 


Moreover, we now have created a bean that a software developer can own, such that functionality may be refined and modified without the need for changes to the HTML or markup within the JSP source page.

Another way to think about these changes is that we have created cleaner abstractions in our system
by replacing implementation with intent. In other words, we have taken a bunch of code from our JSP source (the Java code that writes the guesses to a file on disk ), encapsulated it within a bean, and replaced it with our intent, which is to store the data, worker1.store().

Looping in JSP

So why might one choose to embed Java code in a JSP as opposed to using a predefined tag? An example would be in order to loop through some data and format HTML for output.

Earlier versions of the JSP specification included a tag syntax for looping through indexed properties of JavaBeans, so that no Java code was needed within the HTML for this purpose.

With the JSP software specification version 1.0, such tags were removed in favor of the creation of an extensible custom tag markup mechanism that could be used for this purpose and much more. Unfortunately, this custom tag functionality is first available in version 1.1 of the specification, and JSP engines supporting the custom tag libraries are only now becoming available.

Further Refinements

After deploying this solution, our expectant family decides to limit the group of people who are able to access the system, deciding to include only their family and friends. To this end, they decide to add an authentication mechanism to their system so that each individual will have to provide proof of identity before accessing the system.

If a simple authentication mechanism is added to the top of our JSP page and we want to ensure that each JSP page is protected by this device, then we will need to add some code to each and every JSP page to execute this authentication check. Whenever there is a duplication of code such as this, it is beneficial to explore options for migrating the duplicated code to a common area.

In the previous example we "factored back," as we moved business logic and data-access Java code from our JSP to our JavaBean, and in the next section we expand our example to "factor forward" into a Servlet, continuing our efforts to minimize the amount of inline Java code in our JSPs.

prev .... | next ....

Back to main


Copyright 1998, 1999, 2000 David Reilly

Privacy | Legal | Linking | Advertise!

Last updated: Monday, June 05, 2006