2. Building Model Components | Contributors: - Craig R. McClanahan
- Mike Schachter
- Ted Husted
- Martin Cooper
- Phil Steitz
|
2.1 Overview |
Many requirements documents used for building web applications focus on
the View.
However, you should ensure that the processing required for each submitted
request is also clearly defined from the Model's perspective.
In general, the developer of the Model components will be focusing
on the creation of JavaBeans classes that support all of the functional
requirements.
The precise nature of the beans required by a particular application will
vary widely depending on those requirements, but they can generally be
classified into several categories discussed below.
However, a brief review of the concept of "scope" as it relates to beans
and JSP is useful first.
|
2.2 JavaBeans and Scope |
Within a web-based application, JavaBeans can be stored in (and accessed
from) a number of different collections of "attributes".
Each collection has different rules for the lifetime of that collection,
and the visibility of the beans stored there.
Together, the rules defining lifetime and visibility are called the
scope of those beans.
The JavaServer Pages (JSP) Specification defines scope choices using
the following terms (with the equivalent servlet API concept defined in
parentheses):
-
page - Beans that are visible within a single JSP page,
for the lifetime of the current request.
(Local variables of the
service method)
-
request - Beans that are visible within a single JSP page,
as well as to any page or servlet that is included in this page,
or forwarded to by this page.
(Request attributes)
-
session - Beans that are visible to all JSP pages and
servlets that participate in a particular user session, across one
or more requests.
(Session attributes)
-
application - Beans that are visible to all JSP pages and
servlets that are part of a web application.
(Servlet context attributes)
It is important to remember that JSP pages and servlets in the same
web application share the same sets of bean collections.
For example, a bean stored as a request attribute in a servlet like this:
MyCart mycart = new MyCart(...);
request.setAttribute("cart", mycart);
is immediately visible to a JSP page which this servlet forwards to,
using a standard action tag like this:
<jsp:useBean id="cart" scope="request"
class="com.mycompany.MyApp.MyCart"/>
|
2.3 ActionForm Beans |
Note: While ActionForm beans often have properties that
correspond to properties in your Model beans, the form beans themselves
should be considered a Controller component.
As such, they are able to transfer data between the Model and View layers.
The Struts framework generally assumes that you have defined an
ActionForm bean (that is, a Java class extending the
ActionForm class) for the input forms in your
application.
ActionForm beans are sometimes just called "form beans".
These may be finely-grained objects, so that there is one
bean for each form, or coarsely-grained so that one bean serves
several forms, or even an entire application.
If you declare such beans in your Struts
configuration file (see "
Building the Controller Components"), the Struts controller servlet
will automatically perform the following services for you, before
invoking the appropriate Action method:
-
Check for an instance of a bean of the appropriate class, under the appropriate key,
in the appropriate scope (request or session).
-
If there is no such bean instance available, a new one is
automatically created and added to the appropriate scope (request or session).
-
For every request parameter whose name corresponds to the name
of a property in the bean, the corresponding setter method will
be called. This operates in a manner similar to the standard
JSP action
<jsp:setProperty> when you use the
asterisk wildcard to select all properties.
-
The updated
ActionForm bean will be passed to the
execute method of an Action class
[org.apache.struts.Action ], so that the values can
be made available to your system state and business logic beans.
For more about coding Actions and ActionForm
beans, see the "Building
Controller Components" chapter.
You should note that a "form", in the sense discussed here, does not
necessarily correspond to a single JSP page in the user interface.
It is common in many applications to have a "form" (from the user's
perspective) that extends over multiple pages.
Think, for example, of the wizard style user interface that is commonly
used when installing new applications.
Struts encourages you to define a single ActionForm bean that
contains properties for all of the fields, no matter which page the field
is actually displayed on.
Likewise, the various pages of the same form should all be submitted to
the same Action Class.
If you follow these suggestions, the page designers can rearrange the
fields among the various pages, often without requiring changes to the
processing logic.
Smaller applications may only need a single ActionForm to service all of
its input forms.
Others applications might use a single ActionForm for each major subsystem
of the application.
Some teams might prefer to have a separate ActionForm class for each
distinct input form or workflow.
How many or how few ActionForms to use is entirely up to you.
The framework doesn't care.
|
2.4 System State Beans |
The actual state of a system is normally represented as a set of one or
more JavaBeans classes, whose properties define the current state.
A shopping cart system, for example, will include a bean that represents
the cart being maintained for each individual shopper, and will (among
other things) include the set of items that the shopper has currently
selected for purchase.
Separately, the system will also include different beans for the user's
profile information (including their credit card and ship-to addresses),
as well as the catalog of available items and their current inventory
levels.
For small scale systems, or for state information that need not be kept
for a long period of time, a set of system state beans may contain all the
knowledge that the system ever has of these particular details.
Or, as is often the case, the system state beans will represent
information that is stored permanently in some external database (such as
a CustomerBean object that corresponds to a particular row in
the CUSTOMERS table), and are created or removed from the server's memory
as needed.
Entity Enterprise JavaBeans are also used for this purpose in large scale
applications.
|
2.5 Business Logic Beans |
You should encapsulate the functional logic of your application as
method calls on JavaBeans designed for this purpose.
These methods may be part of the same classes used for the system state
beans, or they may be in separate classes dedicated to performing the
logic.
In the latter case, you will usually need to pass the system state beans
to be manipulated to these methods as arguments.
For maximum code re-use, business logic beans should be designed and
implemented so that they do not know they are being executed in a
web application environment.
If you find yourself having to import a javax.servlet.* class
in your bean, you are tying this business logic to the web application
environment.
Consider rearranging things so that your Action classes (part
of the Controller role, as described below) translate all required
information from the HTTP request being processed into property setter
calls on your business logic beans, after which a call to an
execute method can be made.
Such a business logic class can be reused in environments other than the
web application for which they were initially constructed.
Depending on the complexity and scope of your application, business logic
beans might be ordinary JavaBeans that interact with system state beans
passed as arguments, or ordinary JavaBeans that access a database using
JDBC calls.
For larger applications, these beans will often be stateful or stateless
Enterprise JavaBeans (EJBs) instead.
For more about using a database with your application, see the
Accessing a Database HowTo.
|
|