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

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

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

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

Chuck Cavaness

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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








14.5 Using Definitions


So far, we've
seen that using Tiles can add value to an application because
you're able to organize the layout of a page into a
single resource, the layout JSP page. This can save development time
and, more importantly, the time it takes to change the layout for an
application. However, there is a problem with the approach used in
the Storefront application shown earlier. In each of the non-layout
tiles, there is redundant code that specifies what content to use for
the header, menubar, and
copyright contentthe same attributes are
being passed in every page. This may not always be the case, but in
general, these values will be constant throughout an application. For
instance, the same copyright is typically shown on every page.

It's redundant to have to specify these in every
tile. Ideally, we could declare these attributes in one place, and
the tiles could include just the page-specific attributes where
needed. Tiles definitions provide just such
functionality. A definition allows you to statically specify the
attributes that are used by a template, which in turn allows you to
specify only the page-specific attributes in your tiles. Definitions
enable you to:

  • Centralize declaration of page description

  • Avoid repetitive declaration of nearly identical pages (by using
    definition inheritance)

  • Avoid creation of intermediate components used to pass parameters

  • Specify the name of a definition as a forward in
    the Struts configuration file

  • Specify the name of a definition as component parameters

  • Overload definition attributes

  • Use a different copy of a component, depending on the locale (I18N)

  • Use a different copy of a component, depending on a key (this might
    be used to show different layouts depending on the client type)


Definitions can be declared in a JSP page or an XML file. Either way,
you should strive to keep the definitions in a central place. If you
are planning on using a JSP page to specify your definitions, put all
the definitions for your application in a single page.
Don't spread your definitions throughout your site,
as that will only make maintenance more difficult.


14.5.1 Declaring Definitions in a JSP Page


As previously mentioned, there are two
locations in which you can specify definitions: a JSP page or an XML
file. We'll discuss the JSP page approach first.

To use the JSP approach, create a JSP page and declare all of your
definitions in that file. For the Storefront application,
we've created a file called
storefront-defs.jsp and put the default
definition in it, as Example 14-6 shows.


Example 14-6. Declaring tiles definitions in a JSP page

<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<tiles:definition
id="storefront.default"
page="/layouts/storefrontDefaultLayout.jsp"
scope="request">
<tiles:put name="header" value="/common/header.jsp" />
<tiles:put name="menubar" value="/common/menubar.jsp" />
<tiles:put name="copyright" value="/common/copyright.jsp" />
</tiles:definition>

The definition in Example 14-6 uses the same layout
tile used earlier. The common files that were spread through the
various tiles are now located in the definition file. This makes
changing their values much easier. For instance, if we wanted to
specify a different copyright page, the only place to change it would
be in the definition file; we would not have to modify every JSP
page.

The definition tag syntax looks very similar to
the syntax for the insert tags shown earlier. We
just need to provide an id attribute and switch
the path attribute to the page
attribute. Also, the default scope for the
definition tag is page. It was
set to request scope here to give it a little broader scope.

To take advantage of the definition, the tile components need to be
able to access it. Because we have given the definition request scope
and it will exist only for the lifetime of a request, we need a way
to include the definition in the various JSP pages. Fortunately, we
already know how to include a JSP page in another page using the JSP
include directive. Example 14-7
shows what the signin.jsp page looks like using
the JSP definition file.


Example 14-7. The signin.jsp page using a tile definition

<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<%@include file="../common/storefront-defs.jsp" %>
<tiles:insert definition="storefront.default">
<tiles:put name="body-content" value="/index.jsp"/>
</tiles:insert>

With this approach, the tile components have to insert only the
page-specific content. Compare Example 14-5. Notice that the
signin.jsp file using the definition needs to
provide only the page-specific content, the
sign-body.jsp file.


14.5.2 Declaring Definitions in a Configuration File


You also have the option of declaring
definitions in a centralized XML file. Whether you use the JSP or the
XML alternative really depends on your requirements. With the XML
approach, you won't need to use the
include directive shown earlier.


14.5.2.1 Creating a definition configuration file

To use the XML approach, create an XML file that follows the syntax
of the tiles-config.dtd file.
The definition XML file should be placed in the
WEB-INF directory, as with the other application
meta-information. The DTD should also be placed in the
WEB-INF directory. Example 14-8
shows an example of a definition XML file.


Example 14-8. The Storefront definition XML file

<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration//EN"
"http://jakarta.apache.org/struts/dtds/tiles-config.dtd">
<tiles-definitions>
<definition name="storefront.default" path="/layouts/storefrontDefaultLayout.jsp">
<put name="header" value="/common/header.jsp" />
<put name="menubar" value="/common/menubar.jsp" />
<put name="copyright" value="/common/copyright.jsp" />
</definition>
</tiles-definitions>

There's not much difference between the definition
format specified in the JSP file in Example 14-6 and
the XML file in Example 14-8. The XML file uses a
slightly different syntax, but it's still very
similar.


The two formats are just similar enough to cause problems. Notice
that in the JSP definition, you use the put tag:

<tiles:put 
name="body-content"
value="../security/signin-body.jsp"/>

but in the XML definition, you use the put element:

<put 
name="header"
value="/common/header.jsp" />

Make sure that you don't get these two confused, as
this can be a difficult bug to track down.

Each definition should have a unique name. JSP tags and pages use the
name to retrieve the definition. It can't be used as
a URL, however; it's only a logical name for the
definition.


14.5.3 Extending Tile Definitions


One
of the most powerful features of tile definitions is the ability to
create new definitions by extending existing ones. All attributes and
properties of the parent definition are inherited, and you can
override any attribute or property. To extend a definition, add the
extends attribute. Example 14-9
shows an example of a definition named
storefront.custom extending the
storefront.default definition.


Example 14-9. Definitions can extend other definitions

<tiles-definitions>
<definition name="storefront.default" path="/layouts/storefrontDefaultLayout.jsp">
<put name="header" value="/common/header.jsp" />
<put name="menubar" value="/common/menubar.jsp" />
<put name="copyright" value="/common/copyright.jsp" />
</definition>
</tiles-definitions>
<tiles-definitions>
<definition name="storefront.custom" extends="storefront.default">
<put name="copyright" value="/common/new-copyright.jsp" />
</definition>
</tiles-definitions>

In Example 14-9, all of the attributes in the
storefront.default definition are inherited.
However, the storefront.customer definition
overrides the value for the copyright attribute
with an alternate copyright page. This is a very powerful feature. If
you have multiple child definitions all extending a root definition,
changing a value in the root definition changes it for all the
children. Thus, you can change the layout in the root definition and
have it changed for all child definitions.


14.5.4 Using Definitions as Forwards in Struts


Tiles definitions can also be used as
Struts forwards, instead of actual URLs. To use definitions in this
manner, you first create the definitions:

<tiles-definitions>  
<definition name="storefront.default"
path="/layouts/storefrontDefaultLayout.jsp">
<put name="header" value="/common/header.jsp" />
<put name="menubar" value="/common/menubar.jsp" />
<put name="copyright" value="/common/copyright.jsp" />
</definition>
<definition name="storefront.superuser.main" extends="storefront.default">
<put name="header" value="/common/super_header.jsp" />
<put name="menubar" value="/common/super_menubar.jsp" />
<put name="copyright" value="/common/copyright.jsp" />
</definition>
</tiles-definitions>

This fragment shows two definitions, the standard default definition
and a second one that defines the layout for a
"superuser." A superuser might be
someone that frequents the site and places many orders, and such a
user might be given more options on the menu bar to facilitate faster
ordering.

In the Struts configuration file, we need to define the forwards that
use these definitions:

<global-forwards>
<forward name="Super_Success" path="storefront.superuser.main" />
</global-forwards>

You can then use the Super_Success forward to send
the user to the storefront.superuser.main
definition just as you would for any other forward.


    / 181