The ability to search a website can be invaluable to visitors. Even if you have a website that searches a product database, your visitors might want to search the contents of your entire site. This article helps you set up such a service. It is excerpted from chapter 10 of the book Better, Faster, Lighter Java, written by Bruce A. Tate and Justin Gehtland (O'Reilly; ISBN: 0596006764).
Adding a Search Service to a Java Application - Implementing the Interface (Page 3 of 4 )
To replace this class, we’re going to write our own controller class called SearchPagesController. It must implement the Controller interface, which defines ourhandleRequestmethod.
public class SearchPagesController implements Controller{ ... }
Here’s our controller’shandleRequestmethod:
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { if (request.getParameter("search") != null) { String keyword = request.getParameter("keyword"); if (keyword == null || keyword.length() == 0) { return new ModelAndView("Error", "message", "Please enter a keyword to search for, then press the search button."); } else { ConfigBean cfg = new ConfigBean(); String indexpath = ""; try { indexpath = cfg.getCurIndexPath(); } catch(Exception ex) { return new ModelAndView("Error", "message", "Could not find current index path."); }
QueryBean qb = new QueryBean(indexpath, keyword, "contents");
qb.execute();
HashMap hits = new HashMap(qb.getResults().length); for(int i =0;i<qb.getResults().length;i++) { hits.put("hits", qb.getResults()[i]); } return new ModelAndView("SearchProducts", hits); } } }
For our search functionality, we won’t use the paged results. We simply list all the results on a single page; as a result, we don’t have to deal with the Next Page and Previous Page code. Our controller again checks for null keywords and returns an error if it finds them empty. Otherwise, the service is used almost identically as the console application in the Chapter 9 was used. First, create an instead ofConfigBeanto find the most current index of the site, then create aQueryBean based on that index path. Finally, execute the query and put all theHitBeaninstances into aHashMapto return to the View.
The usage pattern is identical to that in the last chapter; the only difference is the format of our returned data. Instead of passing the native array ofHitBeansback, theModelAndViewobject requires aHashMap. It’s easy enough to create the one from the other, and now we have an entirely new access point for the Spider application with almost no work.
There is one last detail we need to work out. The originalSearchProductsControllerhas a field calledpetStoreof typePetStoreFacade that the Spring framework populates for it. In order to be a complete replacement for the original, our new controller needs to expose the same property and accessor methods, even though they aren’t officially found on a standalone interface anywhere in the application. You will often find examples of this when you’re extending or modifying an application.
private PetStoreFacade petStore;
public void setPetStore(PetStoreFacade petStore){ this.petStore = petStore; }