Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Apache Struts - From Novice To Professional (2006)

.pdf
Скачиваний:
56
Добавлен:
17.08.2013
Размер:
11.68 Mб
Скачать

158

C H A P T E R 1 3 R E V I E W L A B : E D I T I N G C O N T A C T S I N L I L L D E P

Implementing the Edit Facility

All you need to do is populate and display the full.jsp form once the user clicks on the company name. You have already implemented the code for updating the Contact in the previous lab sessions. Complete the following:

1.Amend listing.jsp to put in the link for the company name. Let the handler be

EditContact.do.

2.Complete the implementation of EditContactAction to load the form data. This Action should forward to full.jsp.

3.Put in an action mapping to tie the path EditContact with EditContactAction and the form ContactForm.

Test out your application to see if the form populates correctly. Also ensure that you can make changes to the contact’s details.

P A R T 2

■ ■ ■

Advanced Struts

As Struts became a common starting point for developers new to the Java platform, an interesting phenomenon was occurring—for many developers, the key perceived value of using Struts was assumed to be the JSP custom tags for HTML forms. While these tags are quite useful, they do not constitute a robust user interface component model, which has led to the need to create or integrate third-party tag libraries for more complex presentation requirements. To me, the core value has always been in the controller tier—the request processing lifecycle, and the features which this lifecycle has enabled, such as the additions of the Tiles framework for reusable look and feel, and the Validator Framework for client-side and server-side enforcement of form validation business rules.

—Craig McClanahan

C H A P T E R 1 4

■ ■ ■

Tiles

Tiles is a Struts plug-in—a piece of software developed independently of Struts, to extend the basic capabilities of Struts.

Tiles was developed initially by Cedric Dumoulin but is now (since version 1.2) integrated into Struts. In fact, it supercedes an older “Template” library, which had provided limited layout capability. The only thing that betrays its previous independent existence is that it’s a plug-in and therefore requires some setup.

Tiles gives Struts applications two new capabilities:

Layouts: The ability to easily provide a uniform “look and feel” to your Struts applications. In most web applications, pages follow a similar layout—for example, they might have a common header or footer or sidebars. Tiles has a elegant inheritance mechanism that allows such layouts, even complicated ones, to be created and maintained easily.

Components: The ability to build reusable GUI components that you can easily embed into your JSP pages. Components give you the flexibility to display dynamic content—content that can change depending on user interaction or on external data sources. An example is displaying a list of weather forecasts for various cities, or a news items that interest the user, or targeted marketing.

In short, layouts provide a common look and feel, and components allow provision of dynamic content in a reusable package.

The powerful thing about Tiles is that you can mix these two capabilities: your layouts may include components. For example, you can specify a layout that displays a component as a sidebar containing a user’s search list. Used wisely, this can lead to easy-to-use applications. You’ll create such a component yourself in the lab section of this chapter.

Of course, both layouts and component behavior can be emulated in other ways. For example, you could enforce a common look and feel by simply pasting the appropriate HTML in your JSP pages. You could implement “components” by cutting and pasting scriptlets in your JSPs!

161

162

C H A P T E R 1 4 T I L E S

If you’ve followed the discussion on MVC in Chapter 5 closely, the shortcomings of these approaches should be obvious. MVC is all about separating code according to their functionality, and violating this principle leads to maintenance woes down the road. So it is with these ad hoc approaches. With them, making site-wide changes to layouts or components are difficult because you’d have to amend each page.

As you will see, Tiles does it better—and easier.

Installing Tiles

To use Tiles, you have to declare it in struts-config.xml. Listing 14-1 shows a typical declaration.

Note Remember, plug-in declarations come last in your struts-config.xml file. Placing it anywhere else will result in an exception being thrown when Struts starts up.

Listing 14-1. Tiles Declaration in struts-config.xml

<plug-in className="org.apache.struts.tiles.TilesPlugin" > <set-property property="definitions-config"

value="/WEB-INF/tiles-defs.xml"/>

</plug-in>

The declaration in Listing 14-1 does two things. First, it tells Struts what plug-in class to instantiate. In this case, it’s org.apache.struts.tiles.TilesPlugin. This plug-in class is responsible for the initialization of Struts.

Second, the <plug-in> tag contains one or more <set-property> tags, each of which passes a parameter-value pair to the plug-in class. In Listing 14-1, the only parameter passed to org.apache.struts.tiles.TilesPlugin is the definitions-config parameter, which points to the relative location of the Tiles definitions file. In this case, it’s /WEB-INF/ tiles-defs.xml.

This tiles-def.xml file (you may call it something else, if you wish—just change the value property if you do) is where you declare layouts and components for Tiles. You can think of it as the Tiles counterpart of struts-config.xml.

Note The Struts distribution contains a tiles-documentation.war file. It contains an example tiles-def.xml file you can use, in the /WEB-INF/ folder of that WAR file.

Listing 14-2 shows the format of the tiles-def.xml file.

C H A P T E R 1 4 T I L E S

163

Listing 14-2. A Blank Tiles Definitions File

<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC

"-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN" "http://struts.apache.org/dtds/tiles-config_1_1.dtd">

<tiles-definitions>

<!-- one or more "definition" tags to define layouts or components. --> </tiles-definitions>

The root tag is <tiles-definitions>, and it contains one or more <definition> tags, with which you declare layouts or components. The next two sections show you how to do this.

Note The Tiles DTD (Document Tag Definition) is stored in the struts.jar file that comes with the Struts distribution. In this JAR file, the path to the DTD is /org/apache/struts/resources/ tiles-config_1_1.dtd. This file also contains the DOCTYPE element used in Listing 14-2. It is also present in the /lib folder of the Struts distribution zip file.

You may split your Tiles definitions into more than one file. This is useful for large projects requiring several sets of look-and-feels or components that have to be maintained separately. Each such Tiles definitions file must follow the format of Listing 14-2, and you’ll have to declare each file in your plug-in declaration. Simply separate the filenames with commas in the <set-property> tag. For example, if you had three Tiles definitions files, A.xml, B.xml, and C.xml, the <set-property> tag would read

<set-property property="definitions-config" value="/WEB-INF/A.xml,/WEB-INF/B.xml,/WEB-INF/C.xml"/>

Lastly, Tiles also uses a custom tag library, struts-tiles.tld. You will have to declare this in your web.xml file (refer to Chapter 3) in order to use this library on your JSPs.

Tiles for Layout

Layouts are a way to create a common look-and-feel for your web application. For example, you might want all JSP pages to have a footer containing copyright information, a side navigation bar, and a header with the company logo.

In Tiles, layouts are just JSP pages. The JSP page for a layout defines the relative placement of sections (body, header, footer, sidebars, etc.) on the displayed page. The content

164

C H A P T E R 1 4 T I L E S

of each section is defined by <tiles:insert> tags, which point to other HTML or JSP pages holding content. Listing 14-3 is a simple layout containing a title, header, body, and footer sections.

Listing 14-3. simple-layout.jsp, a Simple Layout with Title, Header, Body, and Footer

<%@ taglib uri="/tags/struts-tiles" prefix="tiles" %> <html>

<head>

<title> <tiles:getAsString name="title"/> </title> </head>

<body>

<table>

<tr><td> <tiles:insert attribute="header"/> </td></tr> <tr><td> <tiles:insert attribute="body"/> </td></tr> <tr><td> <tiles:insert attribute="footer"/> </td></tr>

</table>

</body>

</html>

As Listing 14-3 clearly demonstrates, a layout defines just the relative placement of content, not the actual content itself. Figure 14-1 shows the relative placement of the various components of the layout.

Figure 14-1. The relative placement of header, body, and footer in simple-layout.jsp

C H A P T E R 1 4 T I L E S

165

The <tiles:getAsString> tag displays content for the title, and the <tiles:insert> tags display the content corresponding to the attribute or name property. The actual content pointed to by these properties can be defined in either the called JSP or the Tiles definitions file.

For example, suppose myPage.jsp wanted to use the layout of Listing 14-3 (simple-layout.jsp). Listing 14-4 shows what the contents of myPage.jsp might be.

Listing 14-4. myPage.jsp, Which Uses simple-layout.jsp

<%@ taglib uri="/tags/struts-tiles" prefix="tiles" %> <tiles:insert page="/layouts/simple-layout.jsp">

<tiles:put name="title" value="A simple page" /> <tiles:put name="header" value="/common/header.jsp" /> <tiles:put name="footer" value="/common/footer.jsp" /> <tiles:put name="body" value="/mypage-content.jsp" />

</tiles:insert>

All myPage.jsp does is specify (using the <tiles:put> nested tags) which files are to be associated with the header, footer, and body attributes. The title is specified as a string, in this case, "A simple page".

Notice the differences in how <tiles:insert> is used in Listings 14-3 and 14-4:

In the layout JSP (Listing 14-3), the attribute property is used to tell Struts what content it should use to replace the enclosing <tiles:insert> tag. For example, when Struts processes <tiles:insert attribute="header"/> in Listing 14-3, it essentially looks for the value of header on the request object. It then uses this value (a JSP page, or as we will see in the next section, a component) and pastes the content from that page or component in place of the <tiles:insert> tag.

In the called JSP (Listing 14-4), the page property is used to specify a layout, and the output from this layout is used to replace the <tiles:insert> tag. The nested <tiles:put> tags define Tiles attributes on the request object. The layout reads these attributes in order to create its output. For example, when Struts processes the <tiles:insert> in Listing 14-4, it knows it must use the layout file /layouts/ simple-layout.jsp. In this layout file, there are a few <tiles:insert> tags that require the header, footer, and body attributes to be created. The values for each is defined in the calling JSP using <tiles:put> tags.

It is important to note that the attributes defined using a <tiles:put> tag will only apply to the layout defined in the enclosing <tiles:insert page="..."> tag. In the unlikely event that you had two <tiles:insert page="..."> tags on your called JSP page, you would have to specify the attributes for each separately. The attributes between these two tags are not shared.

166

C H A P T E R 1 4 T I L E S

Note The page, template, and component properties of the <tiles:insert> tag are synonymous. You might want to use a different synonym to indicate if a layout or Tiles component (see the next section) is used. This simply improves readability.

The other way to specify the values of the attribute or name property is to create a definition within the Tiles definitions file. For example, you could move part of Listing 14-4 into the Tiles definitions file, as shown in Listing 14-5.

Listing 14-5. tiles-def.xml, with a Single Definition

<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC

"-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN" "http://struts.apache.org/dtds/tiles-config_1_1.dtd">

<tiles-definitions>

<definition name=".simple" path="/layouts/simple-layout.jsp"> <tiles:put name="header" value="/common/header.jsp" /> <tiles:put name="footer" value="/common/footer.jsp" /> </definition>

</tiles-definitions>

Listing 14-5 shows a Tiles definitions file called .simple (the meaning of the leading dot will be obvious shortly). This definition defines just two attributes, header and footer. To use the .simple definition in a JSP, see Listing 14-6.

Listing 14-6. myPage2.jsp, Which Uses a Tiles Definition

<%@ taglib uri="/tags/struts-tiles" prefix="tiles" %> <tiles:insert definition=".simple">

<tiles:put name="title" value="A simple page" /> <tiles:put name="body" value="/mypage-content.jsp" />

</tiles:insert>

Listings 14-5 and 14-6 together show how to use a Tiles definition instead of a layout path. Shared attributes are the ones defined in the Tiles definitions file, while attributes specific to a called JSP page are defined on that page. This makes sense, because you might want to fix the header and footer but change the title and body of the displayed page.

Note

C H A P T E R 1 4 T I L E S

167

Quick Quiz

What advantage does this approach (Listings 14-5 and 14-6) have over the earlier one (Listing 14-4)?

Tiles layout definitions can even be “subclassed.” For example, suppose we wanted a new definition similar to the old one (in Listing 14-5), but where the title was fixed and the footer was changed. Listing 14-7 shows the amended definitions file.

Listing 14-7. tiles-def.xml, with a New Definition

<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC

"-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN" "http://struts.apache.org/dtds/tiles-config_1_1.dtd">

<tiles-definitions>

<definition name=".simple" path="/layouts/simple-layout.jsp"> <tiles:put name="header" value="/common/header.jsp" /> <tiles:put name="footer" value="/common/footer.jsp" /> </definition>

<definition name=".simple.admin" extends=".simple" > <tiles:put name="title" value="Admin Zone" />

<tiles:put name="footer" value="/common/admin-footer.jsp" /> </definition>

</tiles-definitions>

The extends property indicates that the new definition named .simple.admin borrows all properties and attributes from the base .simple definition.

That’s the rationale behind the . separator—you can tell at once that .simple has no ancestor definitions, and that .simple.admin descends directly from .simple.

The nested <tiles:put> tags either override certain attributes (footer) or add new ones (title). The new definition is used in exactly the same way as the old one.

The last way to define and use layouts is to define them completely in the Tiles definitions file. Continuing from Listing 14-7: