Presentation Approach


The servlet-centric architecture selected for bigrez.com uses JSP pages for all display- related components . JSP pages will therefore be used to display business data, forms, search results, and all visual elements that define the overall design of the site. As shown in Figure 3.2, the site includes navigation bars, headers and footers, and a left-side gutter containing the current reservation information and targeted offers. We must now decide how this overall table structure will be defined and who will be responsible for assembling the generated HTML into a single response to the user .

A very common design pattern, the composite view pattern , is often used for this purpose. This pattern recognizes the importance of placing individual pieces of content in separate view components, in our case either stand-alone JSP pages or snippets of JSP code. As discussed in the literature, the overall page is then assembled by some manager or controller in the architecture that knows the proper placement of each view

component on the final page and is responsible for creating the top-level HTML tags and structure for the page. The specific technique used to include the separate view components is not defined by the pattern and can include translation-time < %@ include ... % > directives, dynamic jsp:include techniques, or more sophisticated techniques using helper objects or custom tags.

We ll employ the composite view pattern in the construction of our example application by breaking the overall page into six different view components, as illustrated by Figure 3.5. Each of these view components will be a separate, stand-alone JSP page included in the overall HTML response using the jsp:include dynamic include capability. The information generated by the primary display page will be located in the framed area to the right of the reservation information and offers areas in the left gutter.

click to expand
Figure 3.5:  bigrez.com primary view components and layout.

So far, so good, but we re not done yet. Which component or page, exactly, is going to define the overall page structure, generate the top-level HTML tags such as < body > and < table >, and use jsp:include elements to assemble the page? Will each display page in the site include the proper view components to assemble the overall response, a commonly used technique we ve labeled self-assembly ? Or will some master page or template be responsible for creating the overall HTML response and including the specific display page in the response, a technique we ve called master page assembly ? Let s examine these two options in more detail and make a design decision for the bigrez.com example application.

Self-Assembly

In the self-assembly technique, the display page assembles all of the supporting pieces of the overall response. The display page basically includes the view components or code snippets required to create the proper HTML table structure and embed all of the headers, footers, and other visual elements in their proper locations. The SimpleHome _ SA.jsp page, presented in Listing 3.1, illustrates how the bigrez.com home page might be constructed using the self-assembly technique.

Listing 3.1:  SimpleHome_SA.jsp showing self-assembly.
start example
 <%@ page extends="com.bigrez.ui.MyJspBase" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head>      <title>Welcome to BigRez.com!</title>   <link rel=stylesheet type="text/css" href="css/StyleMaster.css">   <script src="/js/DatePicker.js"></script>    </head> <body bgcolor="#FFFFFF"> <table align="center" width="725" cellpadding="0" cellspacing="0"        border="0">   <tr>     <td>       <table align="center" cellpadding="0" cellspacing="10">         <tr>           <td align="center">             <jsp:include page="/  Header.jsp  "></jsp:include>           </td>         </tr>         <tr>           <td>             <jsp:include page="/  TopNav.jsp  "></jsp:include>           </td>         </tr>       </table>     </td>   </tr> </table> <table align="center" width="725" cellpadding="0" cellspacing="0"        border="0">   <tr>     <td width="175" valign="top" bgcolor="#EEEEEE">       <table width="175" border="0" cellpadding="0" cellspacing="0">       <tr>         <td><jsp:include page="/  RezInfo.jsp  "/></td>       </tr>       <tr>         <td><jsp:include page="/  Offers.jsp  "/></td>       </tr>       </table>     </td>     <td width="1" >       <img src="images/space.gif" width="1" height="1">     </td>     <td width="550" valign="top">  Home Page Contents Here..  </td>   </tr> </table> <table align="center" width="725" cellpadding="0" cellspacing="0"        border="0">   <tr>     <jsp:include page="/  Footer.jsp  "/>   </tr> </table> </body> </html> 
end example
 

The five common components ( Header.jsp , TopNav.jsp , RezInfo.jsp , Offers.jsp , and Footer.jsp ) are included in the HTML response at the proper location in the overall page structure and table layout. In this simple technique, a large amount of the structure and layout would have to be copied to all display pages in the site, making maintenance and customization for different installations difficult. This simple type of self-assembly is suitable for only the smallest Web applications.

The basic self-assembly approach can be improved by combining the sections above and below the display page content itself in additional intermediate view components, as illustrated in the BetterHome _ SA.jsp example in Listing 3.2.

Listing 3.2:  BetterHome_SA.jsp showing improved self-assembly.
start example
 <%@ page extends="com.bigrez.ui.MyJspBase" %> <jsp:include page="/  Top_SA.jsp  ">   <jsp:param name="title" value="Welcome to BigRez.com!"/> </jsp:include> <table align="center" width="725"         cellpadding="0" cellspacing="0" border="0">   <tr>     <jsp:include page="/  LeftSide_SA.jsp  "/>     <td width="1" >       <img src="images/space.gif" width="1" height="1">     </td>     <td width="550" valign="top">  Home Page Contents Here..  </td>   </tr> </table> <jsp:include page="/  Bottom_SA.jsp  "/> 
end example
 

These new intermediate view components, Top_SA.jsp , LeftSide_SA.jsp , and Bottom_SA.jsp , basically contain the HTML and lower-level jsp:include tags previously contained in the display page itself, thereby reducing the amount of content copied on each display page. This technique represents a significant improvement over the simple technique, although it too has limitations as the complexity of the page structure surrounding the display content increases .

Because the title of the HTML page is now defined in the common Top_SA.jsp , each display page must provide the title to the included JSP using a request parameter:

 <jsp:include page=/Top_SA.jsp>   <jsp:param name=title value=Welcome to BigRez.com!/> </jsp:include> 

The Top_SA.jsp page must define the title using the passed-in request parameter:

 <head>   <title><%= request.getParameter(title) %></title>   ... </head> 

Note that these self-assembly examples did not include all of the visual elements desired for the bigrez.com site (see Figure 3.2) in order to keep the examples simple. For example, the table containing the LeftSide_SA.jsp component and the actual display page content should have been surrounded by a two- color border. This would complicate the table structure copied in each display page.

Some form of self-assembly would probably work for the bigrez.com site, but we re looking for a technique that provides more flexibility and is easier to maintain. Imagine, for example, that we want to move the reservation information and targeted offers from the left gutter to the right gutter or that we need to add a completely new view component, perhaps something like a bread-crumb navigator, in the table containing the display page. Both of these changes would require touching all of the display pages to modify the table structure and jsp:include directives to reflect the new layout and components.

We d also like to be able to deploy the same application for multiple hotel chains or customers. What if a potential new customer demands a different layout? The display pages or intermediate view components would have to be copied and edited to create a new layout, hurting maintainability, or would require conditional code to assemble the page differently based on the client, adding complexity. Neither solution provides a clean, easy mechanism to reuse the application in the face of significant layout changes.

No matter how sophisticated the include process becomes through the use of custom tags, view helpers, or even framework components meant for this purpose, the basic concept of self-assembly is inherently flawed. The individual display pages should know little or nothing about the way in which they are assembled to form the overall page, and self-assembly in all its forms breaks this rule.

What we need is an implementation of the composite view pattern that completely separates the overall structure and layout of the page from the contents of the display area. In the next section, we ll discuss one useful solution: master page assembly .

Master Page Assembly

The self-assembly approach, discussed in the previous section, separated the complete page contents into individual view components and made it the responsibility of the display page itself to include these components in the correct manner to build the full HTML response. The display page was in charge of the assembly process. In the master page assembly approach, on the other hand, the display page is simply another piece of content included in the overall response by a master page. As shown in Figure 3.6, the master page is now in charge of the assembly process and defines the overall page structure and layout.

click to expand
Figure 3.6:  Comparison of self-assembly and master page assembly.

This seems simple enough as a concept, but how can the same master page be used for all the different display pages in the site? How does the master page know which display page to include?

The trick to making this technique work is the run-time evaluation of a jsp:include directive placed in the master page to include the proper content page. Recall that the jsp:include directive had two basic forms. The first is a version using a statically defined page name:

 <jsp:include page=/Home.jsp /> 

The second is a version with the page name defined using a run-time expression:

 <jsp:include page="<%= variablename %>" /> 

The version using a run-time expression as the page name provides one straight-forward way to share the same master page across many display pages. In its simplest form, the Master.jsp page looks for a particular request parameter, page , and uses it in a jsp:include directive to include the proper page in the display area in the overall template defined in the master page:

  ...  <  % String pagename = request.getParameter("page"); %  > ... <body> <table> ...   <  % try { %  >   <  jsp:include page="  <  %= pagename %  >  "/  >   <  % }   catch (IOException e) {   %  >     <  jsp:include page="Blank.jsp"/  >     <  % } %  > ... </table> </body> 

All of the display pages are then accessed using URLs with the master page name and a query-string parameter defining the display page. For example, http:// servername :port/Master.jsp?page=Home.jsp would invoke the Master.jsp master page and provide the name of the display page to include, Home.jsp . Hyperlinks within the pages would likewise specify URLs containing this syntax:

 <A HREF=Master.jsp?page=ViewProperty.jsp>...</A> 

Because we re using Struts to control navigation, if we choose this technique for bigrez.com , the mapping elements in struts-config.xml must also reflect this syntax:

 ... <action path="/PropertyListAction"         type="com.bigrez.ui.PropertyListAction"         name="PropertyForm"         scope="request"         validate="false"         input="  /Master.jsp?page=PropertyList.jsp  ">   <forward name="viewproperty"            path="  /Master.jsp?page=ViewProperty.jsp  " redirect="false"/>   <forward name="success"             path="  /Master.jsp?page=SelectDates.jsp  " redirect="false"/> </action> ... 

We can now make changes to the overall site look and feel by modifying a single page, Master.jsp , without touching any of the display pages. These changes can include a wholesale rearranging of the page structure, the addition or deletion of included view components, and any other desired changes. The master page assembly technique is also forgiving during development because it reacts to a missing display page by displaying a blank page in the display area rather than causing an HTTP 404 error.

The use of URLs containing the master page name plus a parameter defining the included display page is a viable and useful approach for achieving the master page assembly technique in JSP-based Web applications. We could select this approach for bigrez.com and be perfectly content, but before we do, let s examine an alternative technique with some distinct advantages.

Master Page Assembly with Page Display Servlet

Including the page parameter on every request for a display page is not ideal. The full URL appears to the user in the browser, thereby exposing our technique, and all of the path elements in the struts-config.xml file must include the full Master.jsp?page=... syntax. In addition, hard-coding the name of the master page everywhere in the system makes it more difficult to use different master pages depending on some run-time variable or user characteristic. What we need is a mechanism to invoke the master page as if the URL contained the full syntax without requiring that all links and navigation paths contain this syntax.

We recommend the use of a page display servlet mapped to a particular file extension as the best mechanism to achieve the desired master-page-assembly behavior without requiring the full syntax on every link. Essentially, the desired display page is requested using an URL such as Home.page , and the .page extension causes WebLogic Server to invoke a particular servlet, PageDisplayServlet , which translates the request for Home.page into the equivalent request for Master.jsp?page=Home.jsp automatically.

Configuring this technique requires a few simple steps and components. First, the PageDisplayServlet is created to perform the desired mapping. As shown in Listing 3.3, this is a simple servlet that forwards the request to the Master.jsp page and includes the desired display page as a request parameter.

Listing 3.3:  PageDisplayServlet.java.
start example
 package com.bigrez.ui; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class PageDisplayServlet extends HttpServlet {      private static org.apache.log4j.Category LOG =         org.apache.log4j.Category.getInstance("PageDisplayServlet");     private void handlePageRequest(HttpServletRequest request,                                    HttpServletResponse response)          throws ServletException, IOException     {         String page = request.getRequestURI();         // drop leading / and .page suffix         String newpage =              page.substring(1, page.indexOf(".page")) + ".jsp";         LOG.info("Forwarding to /Master.jsp?page=" + newpage);         RequestDispatcher dispatch =             request.getRequestDispatcher("/Master.jsp?page=" +                                          newpage);         dispatch.forward(request,response);     }     public void doGet (HttpServletRequest request,                        HttpServletResponse response)          throws ServletException, IOException     {         handlePageRequest(request,response);     }     public void doPost (HttpServletRequest request,                         HttpServletResponse response)          throws ServletException, IOException     {         handlePageRequest(request,response);     } } 
end example
 

Next, we configure WebLogic Server to invoke this servlet for requests such as Home.page by mapping the .page file extension to the PageDisplayServlet servlet in the web.xml descriptor file:

 <servlet>   <servlet-name>pagedisplay</servlet-name>   <servlet-class>com.bigrez.ui.PageDisplayServlet</servlet-class> </servlet> ... <servlet-mapping>   <servlet-name>pagedisplay</servlet-name>   <url-pattern>*.page</url-pattern> </servlet-mapping> 

That s it! We can now employ the .page syntax for all of the hyperlinks in the system and leave the mapping from Something.page to Master.jsp?page=Something.jsp up to the PageDisplayServlet at request time. This change also simplifies the mapping elements in the struts-config.xml file:

 <action path="/PropertyListAction"         type="com.bigrez.ui.PropertyListAction"         name="PropertyForm"         scope="request"         validate="false"         input="  /PropertyList.page  ">   <forward name="viewproperty"            path="  /ViewProperty.page  " redirect="false"/>   <forward name="success"             path="  /SelectDates.page  " redirect="false"/> </action> 

We could also use multiple master pages and have the PageDisplayServlet choose the correct master page based on user preferences or other run-time criteria.

We selected this version of the master-page-assembly approach for bigrez.com because of the benefits related to maintainability and customization. As you ll see when we walk through the example program in detail, the use of the PageDisplay Servlet helps keep the configuration files and links clean and simple.




Mastering BEA WebLogic Server. Best Practices for Building and Deploying J2EE Applications
Mastering BEA WebLogic Server: Best Practices for Building and Deploying J2EE Applications
ISBN: 047128128X
EAN: 2147483647
Year: 2003
Pages: 125

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