Programming Jakarta Struts, 2nd Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Programming Jakarta Struts, 2nd Edition [Electronic resources] - نسخه متنی

Chuck Cavaness

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








9.4 Extending View Components


There generally is less reason or
need to extend components located within the view layer than there is
to extend components in the controller layer. Typically, views are
written exclusively for an application. For example,
it's unlikely that a JSP page written for one
application will be used within a different application. This is not
always the case, but differences between look-and-feel and content
make such reuse improbable. The one area within the Struts view layer
where extensions often are created, however, is in the JSP tag
libraries.


9.4.1 Extending Struts Custom Tags


The custom tags provided by the Struts
framework can be reused across applications and application domains.
Therefore, it makes sense that customization and extensions are more
likely with these components than with JSP pages. Because the tag
handlers are regular Java classes, specialization is achieved through
subclassing.

Although you can extend any tag, the HTML tag library is the one that
you'll most likely need to customize (mainly because
the custom tags within this library have the greatest impact on the
view content). Regardless of which tags you extend,
you'll need to create your own tag library to hold
your tag extensions.


You could modify the Struts tag libraries and include your new tag
class, but that would make upgrading to newer versions of the Struts
framework much harder. You're better off creating
your own tag library that contains just your
application's tags.

Once you've created a .tld file
for your extensions and registered it with the web application
deployment descriptor, you are free to use your tags just as you
would any others.


9.4.2 Extending Model Components


Because the Struts framework
doesn't provide a great deal of components for the
model layer, extensions to these components are better discussed in
other Java programming books. However, there are two classes that
might be placed into the category of extensible model components.
They aren't the best representations of what a model
component is, but they are responsible for holding model state.


9.4.3 The UserContainer and ApplicationContainer Classes


I've mentioned the UserContainer
and ApplicationContainer classes in previous
chapters without defining exactly what they are. These two classes
are not part of the Struts frameworkI created them as part of
the example Storefront application. The purpose of these two classes
is to store user and application-specific information in instances of
these classes, rather than in the HttpSession and
ServletContext objects, respectively.

One of the problems with storing data in the
HttpSession is that the interface to store and
retrieve data from the session object is not strongly typed. In other
words, the interface for any data is:

public void setAttribute( someString, someObject );
public Object getAttribute( someString );

The client must be aware of the key at which the data is stored in
order to put an object into or retrieve an object from storage. For
example, to store and then retrieve a set of permissions using the
HttpSession, the methods would look like this:

public void setAttribute( permissionsKey, permissionsSet );
public Object getAttribute( permissionsKey );

The programmer would also need to explicitly cast the return value
from the getAttribute() method. Some programmers
prefer a more strongly typed interface instead:

userContainer.setPermissions( permissions );
userContainer.getPermissions( );

Here, the client doesn't have to worry about what
key the object is being stored under or how it's
being stored. It can be an HttpSession object or
some other data store; the client unaware of the store method because
it's not forced to use the methods of the
HttpSession directly.

There's nothing really complicated about the
UserContainer class itself. It's
an ordinary JavaBean that contains instance variables, along with
public getters and setters for the properties. Example 9-5 illustrates a basic UserContainer
class.


Example 9-5. A basic UserContainer class

package com.oreilly.struts.storefront.framework;
import java.util.Locale;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionBindingEvent;
import com.oreilly.struts.storefront.customer.view.UserView;
/**
* Used to store information about a specific user. This class is used
* so that the information is not scattered throughout the HttpSession.
* Only this object is stored in the session for the user. This class
* implements the HttpSessionBindingListener interface so that it can
* be notified of session timeout and perform the proper cleanup.
*/
public class UserContainer implements HttpSessionBindingListener, Serializable {
// The user's shopping cart
private ShoppingCart cart = null;
// Data about the user that is cached
private UserView userView = null;
/**
* The Locale object for the user. Although Struts stores a Locale for
* each user in the session, the locale is also maintained here.
*/
private Locale locale;
public UserContainer( ) {
super( );
initialize( );
}
public ShoppingCart getCart( ) {
return cart;
}
public void setCart(ShoppingCart newCart) {
cart = newCart;
}
public void setLocale(Locale aLocale) {
locale = aLocale;
}
public Locale getLocale( ) {
return locale;
}
/**
* The container calls this method when it is being unbound from the
* session.
*/
public void valueUnbound(HttpSessionBindingEvent event) {
// Perform resource cleanup
cleanUp( );
}
/**
* The container calls this method when it is being bound to the
* session.
*/
public void valueBound(HttpSessionBindingEvent event) {
// Don't need to do anything, but still have to implement the
// interface method.
}
public UserView getUserView( ) {
return userView;
}
public void setUserView(UserView newView) {
userView = newView;
}
/**
* Initialize all of the required resources
*/
private void initialize( ) {
// Create a new shopping cart for this user
cart = new ShoppingCart( );
}
/**
* Clean up any open resources. The shopping cart is left intact
* intentionally.
*/
public void cleanUp( ) {
setUserView( null );
}
}

One thing to notice is that the UserContainer
class in Example 9-5 implements the
HttpSessionBindingListener interface. The methods
of this interface allow the UserContainer to be
notified when it is bound to and unbound from the session. This
allows it to perform any necessary cleanup on the object. An instance
of the UserContainer is created for each new user
at the time the user enters the application. The
UserContainer object itself is stored in the
session, and it must have the duration of the session. If the user
exits and re-enters the site, a new UserContainer
typically is created for that user. The UserContainer
also implements the Serializable interface. This
is necessary in case the container needs to passivate or transfer the
session's contents in a cluster.

The
ApplicationContainer is used for a similar purpose, but at the
application level, not the session level. It's
useful for storing or caching information that is needed by all users
across the application. Things such as selection lists, configuration
properties, and other non-client-specific data that you need to get
once and hold on to are candidates for the
ApplicationContainer class. This class is created
when the application is first started and destroyed when the
application exits.


    / 181