< Day Day Up > |
10.3 The User Interface (JSP)The user interface is fairly straightforward. Instead of just dumping our results to the console or creating an XML document of the results (as in the web service implementation from Chapter 9), this time we need to write a JSP that iterates over the results and displays them as hyperlinks in a table. The original jPetStore search feature used a PagedListHolder for its results because it displayed the image associated with each returned product in the table. Since the images were arbitrary in size, jPetStore didn't want to display too many entries on a given page since it might result in a lot of vertical scrolling. Our results consist of a hyperlink to the returned URL and the relative rank of the given result; therefore, we'll use a simple table to display our results. Again, we are faced with the rewrite-or-replace question. Just like last time, we have three questions to consider:
Because of the rather trivial nature of the changes and because JSPs are easily edited in place (no compilation necessary), we'll just repurpose the existing SearchProducts.jsp file. This strategy saves us from having to change any more configuration settings: <%@ include file="IncludeTop.jsp" %> <table align="left" bgcolor="#008800" border="0" cellspacing="2" cellpadding="2"> <tr> <td bgcolor="#FFFF88"> <a href="<c:url value="/shop/index.do"/>"> <b><font color="BLACK" size="2"> << Main Menu</font></b> </a> </td> </tr> </table> <table align="center" bgcolor="#008800" border="0" cellspacing="2" cellpadding="3"> <tr bgcolor="#CCCCCC"> <td><b>URL</b></td> <td><b>Rank</b></td> </tr> <c:forEach var="page" items="${hits}"> <tr bgcolor="#FFFF88"> <td><a href="<c:out value="${page.url}"/>"> <c:out value="${page.url}"/></a> </td> <td> <c:out value="${page.score}"/> </td> </tr> </c:forEach> </table> <%@ include file="IncludeBottom.jsp" %> The JSP files in the application have a standard header and footer defined in IncludeTop.jsp and IncludeBottom.jsp. All we have to do is render the results in between the include directives. Start by creating a JSP-style forEach loop, with an enumerator called page pointing at each member of the HashMap called "hits." For each hit, we render a table row containing the URL (the value of which is both the text to display and the HREF to point it to) and the relative rank of the hit. JSP handles hooking up the variables and properties using reflection. However, when implementing this page, we come across the first (and only) reason to change some of the original Spider code. 10.3.1 Changes to the Original Code to Fit the JSPJSP reflects on fields to hook up properties to <out> display tags instead of getters and setters. Unfortunately, our original implementation of HitBean marked all of its data private and only exposed getters and setters (normally, the appropriate strategy). Since we now have to have the fields exposed directly, we need to make a simple change to the Spider. The original class started with these declarations: final String url; final String title; final float score; It now has to become: public final String url; public final String title; public final float score; 10.3.2 What if We Don't Have the Spider Source?It is instructive to examine what happens when we aren't the original authors of either the application we are extending (jPetStore) or the service we are integrating (Simple Spider). If we don't have access to the source code of either project, we can still make the extension we've been working on. For the jPetStore, all we did was modify a configuration file and a JSP (which we always have the source for) and add a new class. If we don't have access to the original source for the HitBean class, how can we make it work with the JSP? The answer is simple: write a wrapper class that exposes the correct properties (or just use the already exposed web service interface): public class HitBeanWrapper { private HitBean _hitbean; public String url; public String title; public float score; public HitBeanWrapper(HitBean hitbean) { _hitbean = hitbean; url = hitbean.getUrl( ); title = hitbean.getTitle( ); score = hitbean.getScore( ); } public String getScoreAsString( ) { return _hitbean.getScoreAsString( ); } } This requires a change to the handleRequest method of the SearchPagesController, as well: HashMap hits = new HashMap(qb.getResults( ).length); for(int i =0;i<qb.getResults( ).length;i++) { hits.put("hits", new HitBeanWrapper(qb.getResults( )[i])); } return new ModelAndView("SearchProducts", hits); That's it. We've edited the Spider all we need to in order to incorporate it into the jPetStore application. 10.3.3 Principles in Action
|
< Day Day Up > |