Chapter 8: Declarative Exception Handling


Adding Tiles to the Mini HR Application

Now that you've reviewed the benefits of using the Tiles framework and how it works, you are ready to update the Mini HR application to use Tiles. Following is the list of steps that you must follow to add Tiles to the Mini HR application:

  1. Create layout JSPs.

  2. Update existing JSPs to work with layouts.

  3. Create a tiles-defs.xml Tiles configuration file.

  4. Update the struts-config.xml Struts configuration file.

  5. Repackage and run the updated application.

The following sections walk through each step of the process in detail.

Create Layout JSPs

This first step demonstrates how to create one layout, to illustrate the basic concepts of Tiles. This layout will be based on the structure of the application's existing pages. Following is the original search.jsp page that will be used to extract the common template:

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>     <html> <head> <title>ABC, Inc. Human Resources Portal - Employee Search</title> </head> <body>     <font size="+1"> ABC, Inc. Human Resources Portal - Employee Search </font><br> <hr width="100%" noshade="true">     <html:errors/>     <html:form action="/search">     <table> <tr> <td align="right"><bean:message key="label.search.name"/>:</td> <td><html:text property="name"/></td> </tr>     <tr> <td></td> <td>-- or --</td> </tr> <tr> <td align="right"><bean:message key="label.search.ssNum"/>:</td> <td><html:text property="ssNum"/> (xxx-xx-xxxx)</td> </tr> <tr> <td></td> <td><html:submit/></td> </tr> </table>     </html:form>     <logic:present name="searchForm" property="results">     <hr width="100%" size="1" noshade="true">     <bean:size  name="searchForm" property="results"/> <logic:equal name="size" value="0"> <center><font color="red"><cTypeface:Bold>No Employees Found</b></font></center> </logic:equal>     <logic:greaterThan name="size" value="0"> <table border="1"> <tr> <th>Name</th> <th>Social Security Number</th> </tr> <logic:iterate  name="searchForm" property="results"> <tr> <td><bean:write name="result" property="name"/></td> <td><bean:write name="result" property="ssNum"/></td> </tr> </logic:iterate> </table> </logic:greaterThan>     </logic:present>     </body> <html>

The body content of the page is shown in bold. This section will be different for each distinct page. The rest of the page, however, will be consistent across several pages, thus allowing for it to be abstracted into a general-purpose layout.

There are three JSP files that make up the layout: mainLayout.jsp, header.jsp, and footer.jsp. The mainLayout.jsp file is shown here:

<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %>     <html> <head>     <title><tiles:getAsString name="title"/></title> </head> <body>     <tiles:insert attribute="header"/>     <tiles:insert attribute="body"/>     <tiles:insert attribute="footer"/>     </body> </html>

This JSP defines the layout's template and is used to source in the other layout JSPs as well as the body content that will be defined by pages utilizing the layout. The body content and other layout JSPs are sourced in with <tiles:insert> tags. These tags specify the names of attributes defined in the Tiles configuration file whose values are the names of the JSPs that should be inserted into the JSP at run time. Notice the use of the <tiles:getAsString> tag. This tag works similarly to the <tiles:insert> tag, but instead of using the specified attribute's value as the name of a page to include, it is used as a literal string. This is useful for defining variables that can be customized by page definitions that extend layout definitions in the Tiles configuration file.

Following are the header and footer layout JSPs. header.jsp:

<font size="+1">ABC, Inc. Human Resources Portal</font><br> <hr width="100%" noshade="true">

footer.jsp:

<hr width="100%" noshade="true"> Copyright &copy; ABC, Inc.

As you can see, the header.jsp and footer,jsp files are quite simple and do not contain much HTML. The content of these JSPs could have been placed directly in the mainLayout. jsp file instead of here and content pages would still only have to contain the body content of the page. However, breaking the pages up into smaller chunks allows for more flexibility in how layouts are used. For example, if you wanted all pages to have the standard header and footer, you wouldn't have to worry about changing anything. On the other hand, if you needed some pages to have a custom header and footer and others to use the standard ones, separating the header and footer into discrete chunks would allow you to do that. You would simply define values for the header and footer attributes at the layout level, and each page that wanted a custom header, footer, or both would override the necessary attributes with new values at the page level. This will make more sense after you see the Tiles configuration file, which is discussed shortly.

Update Existing JSPs to Work with Layouts

Once you have created the layout JSPs, the next step is to update the application's original JSPs to contain only the body content of their pages. To do this, you must remove each of the pieces of the original page that were used to craft the common layout. Following is the updated search.jsp page containing only body content:

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>     <html:errors/>     <html:form action="/search">     <table> <tr> <td align="right"><bean:message key="label.search.name"/>:</td> <td><html:text property="name"/></td> </tr> <tr> <td></td> <td>-- or --</td> </tr> <tr> <td align="right"><bean:message key="label.search.ssNum"/>:</td> <td><html:text property="ssNum"/> (xxx-xx-xxxx)</td> </tr> <tr> <td></td> <td><html:submit/></td> </tr> </table>     </html:form>     <logic:present name="searchForm" property="results">     <hr width="100%" size="1" noshade="true">     <bean:size  name="searchForm" property="results"/> <logic:equal name="size" value="0"> <center><font color="red"><cTypeface:Bold>No Employees Found</b></font></center> </logic:equal>     <logic:greaterThan name="size" value="0"> <table border="1"> <tr> <th>Name</th> <th>Social Security Number</th> </tr> <logic:iterate  name="searchForm" property="results"> <tr> <td><bean:write name="result" property="name"/></td> <td><bean:write name="result" property="ssNum"/></td> </tr> </logic:iterate> </table> </logic:greaterThan>     </logic:present> 

As you can see, the updated page no longer contains the header or footer portions of the content. The search page did not have a true footer, so the content placed in the footer.jsp file is new. At run time, the layout JSPs will surround the contents of this updated page with the common layout content to create the complete page.

Because the search.jsp page contains only body content now, linking directly to it from the index.jsp page is no longer a valid option. Instead, the link to the search page needs to point to the Tiles definition for the search page. This is accomplished by linking to an action mapping that forwards to the Tiles definition. The updated index.jsp is shown next with the updated link in bold:

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>     <html> <head> <title>ABC, Inc. Human Resources Portal</title> </head> <body>     <font size="+1">ABC, Inc. Human Resources Portal</font><br>     <hr width="100%" noshade="true">     &#149; Add an Employee<br> &#149; <html:link action="/viewSearch">Search for Employees</html:link><br>     </body> </html>

Create a tiles-defs.xml Tiles Configuration File

As mentioned, there are two ways to declare Tiles layouts: with Tiles tags in a master JSP that gets included into each of the layout JSPs or by declaring them in an XML configuration file. This example uses the configuration file option because it is the most flexible and easy to maintain approach. Following is the tiles-defs.xml file that declares the layouts. This file should be placed inside the Mini HR /WEB-INF/ folder.

<?xml version="1.0"?>     <!DOCTYPE tiles-definitions PUBLIC   "-//Apache Software Foundation//DTD Tiles Configuration 1.3//EN"   "http://struts.apache.org/dtds/tiles-config_1_3.dtd">     <tiles-definitions>       <!-- Main Layout -->   <definition name="main.layout" path="/mainLayout.jsp">     <put name="title"  value=""/>     <put name="header" value="/header.jsp"/>     <put name="body"   value=""/>     <put name="footer" value="/footer.jsp" />   </definition>       <!-- Search Page -->   <definition name="search.page" extends="main.layout">     <put name="title"         value="ABC, Inc. Human Resources Portal - Employee Search"/>      <put name="body"   value="/search.jsp"/>   </definition>     </tiles-definitions>

There are two Tiles definitions in this file. The first definition in the file declares a layout named main.layout. The .layout extension given to the definition's name is used to denote that it is a layout definition. This is not a formal naming scheme; however, it is a simple way to distinguish the types of definitions. Generally speaking, layout definitions specify the template for a page and the list of attributes whose values will be used to fill in the template. Page definitions extend layout definitions and provide values for the attributes defined in the extended layout. So, essentially, page definitions are instances of a layout with attributes set to the content for a specific page.

Notice that the first definition defines four attributes with put tags. These attributes will be available for use by the layout JSP specified by the path attribute. The layout JSP uses these attributes to supply it with the locations of its content. Additionally, attributes can be used to supply literal strings, as is the case with the title attribute. This attribute will be used by mainLayout.jsp to enable a dynamic title based on the value set by page definitions that extend the layout definition.

The second definition in the file declares a page definition named search.page. This definition extends the main.layout layout definition and supplies values for the attributes that don't have values in the layout definition. This definition can override any of the attributes in the layout definition if so desired; however, only the title and body attributes are overridden in this case.

Update the struts-config.xml Struts Configuration File

After you have created the Tiles configuration file, you must update Mini HR's struts-config.xml file to point to Tiles definitions instead of pointing directly to JSPs for each page that has been converted to use Tiles. You also must add a new action mapping that forwards to the search page for the link in the index.jsp page. Additionally, the Tiles plugin must be added to the file.

Without Tiles, forward and action definitions point directly to JSPs. With Tiles, they point to the page's definition in the Tiles configuration file. For example, before, the search action pointed directly to search.jsp, as shown here:

<action path="/search"         type="com.jamesholmes.minihr.SearchAction"         name="searchForm"        scope="request"     validate="true"        input="/search.jsp"/>

However, now the action will point to the search page's Tiles definition, as shown here:

<action path="/search"         type="com.jamesholmes.minihr.SearchAction"         name="searchForm"        scope="request"     validate="true"        input="search.page"/>

At run time, the Tiles plugin will determine if a specified page is the name of a Tiles definition or an actual path to a page. If a Tiles definition is specified, then Tiles will process the page accordingly; otherwise, normal Struts processing will take place.

Because the search.jsp page contains only body content now, linking directly to it from the index.jsp page is no longer a valid option. Instead, the link to the search page needs to point to the Tiles definition for the search page. To accomplish that, an action mapping that forwards to the Tiles definition must be added to the Struts configuration file, as shown next:

<action path="/viewSearch"      forward="search.page"/>

This action mapping then is referenced via the HTML Tag Library's link tag from the index. jsp page.

To add the Tiles plugin to the application, you must add the following snippet to struts-config.xml:

<!-- Tiles Configuration --> <plug-in className="org.apache.struts.tiles.TilesPlugin">   <set-property property="definitions-config"                    value="/WEB-INF/tiles-defs.xml"/> </plug-in>

This causes Struts to load the Tiles plugin at application startup. Notice that the Tiles configuration file is specified with the set-property tag. You can specify multiple configuration files by providing a comma-delimited list of files.

The following code shows the updated Struts configuration file for Mini HR in its entirety. The sections that have changed or that have been added are shown in bold.

<?xml version="1.0"?>     <!DOCTYPE struts-config PUBLIC   "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"   "http://struts.apache.org/dtds/struts-config_1_3.dtd">     <struts-config>       <!-- Form Beans Configuration -->   <form-beans>     <form-bean name="searchForm"                type="com.jamesholmes.minihr.SearchForm"/>   </form-beans>       <!-- Action Mappings Configuration -->   <action-mappings>     <action path="/viewSearch"          forward="search.page"/>         <action path="/search"             type="com.jamesholmes.minihr.SearchAction"             name="searchForm"            scope="request"         validate="true"            input="search.page"/>   </action-mappings>       <!-- Message Resources Configuration -->   <message-resources     parameter="com.jamesholmes.minihr.MessageResources"/>       <!-- Tiles Configuration -->   <plug-in className="org.apache.struts.tiles.TilesPlugin">     <set-property property="definitions-config"                      value="/WEB-INF/tiles-defs.xml"/>   </plug-in>     </struts-config>

Repackage and Run the Updated Application

Because no Java code was modified during this process, it's not necessary to recompile the Mini HR application. However, several files have been added and a few have been modified, so the application needs to be repackaged and redeployed before it is run. Assuming you've made modifications to the original Mini HR application and it was set up in the c:\java\MiniHR directory (as described in Chapter 2), the following command line will repackage the application when run from c:\java\MiniHR:

jar cf MiniHR.war *

Similar to the way you ran Mini HR the first time, you now need to place the new MiniHR.war file that you just created into Tomcat's webapps directory, delete the webapps/MiniHR directory, and start Tomcat. As before, to access the Mini HR application, point your browser to http://localhost:8080/MiniHR/. Once you have the updated Mini HR running, everything should work as it did before. However, now you can add new pages and make global changes to the application with minimal effort.



Struts. The Complete Reference
Struts: The Complete Reference, 2nd Edition
ISBN: 0072263865
EAN: 2147483647
Year: 2004
Pages: 165
Authors: James Holmes

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net