Using the GWT SuggestBox with RPC – Part Three

July 27th, 2008 Alex Moffat Posted in EffectiveGWT, GWT | No Comments »

Following on from Part One and Part Two this final post describes a SuggestOracle implementation that returns suggestions from a servlet. All of the code examples are available for download. There are three guidelines to the design of the RPC based SuggestOracle.

First, avoid the problem I described in Part One where an optimization in the SuggestBox to deal with an empty query string coupled with slower responses from the SuggestOracle can lead to the suggestion drop down appearing when the SuggestBox itself is empty. This is prevented by checking the length of the query string and returning an empty list for single character queries.

Second, use only one connection to the server. As shown in Part Two IE6 and IE limit you to two open connections to the server at once. This design uses a single connection leaving one free if needed.

Third, limit the number of times the server is called by using, if possible, results from an earlier request to the server to satisfy a later one.

Looking at the ServerSuggestOracle class in the downloadable examples the overall flow is, first save the query that’s being made and if there isn’t a request already in progress return some suggestions. This takes care of the second guideline. If there is a request in progress then when it returns it will take care of responding to the caller using the request saved here. In this way the most recently issued request is always responded to regardless of any delay in getting a response from the server.


 public void requestSuggestions(final Request request, final Callback callback) {
    // Record this request as the most recent one.
    mostRecentClientRequest = request;
    // If no request running at the moment return some suggestions.
    if (!requestInProgress) {
        returnSuggestions(callback);
    }
 }

The next step is in the returnSuggestions method. The first thing this does is deal with the case of a single character query by returning an empty list. This handles the first guideline.


 if (mostRecentQuery.length() == 1) {
     callback.onSuggestionsReady(mostRecentClientRequest,
         new Response(Collections.<Suggestion>emptyList()));
     return;
 }

Then, to handle guideline three, the code checks whether there is already data from the server that can satisfy the current request. Whether this is possible depends on two things.

First, the relationship between the complete set of suggestions for a query string and the complete set of suggestions for a longer query string for which the first one is a prefix. For instance the strings "al" and "ale". If all of the suggestions for "ale" are a subset of the suggestions for "al", then if we already have all the "al" suggestions on the client we can filter them on the client to produce the suggestions of "ale". For the prefix matching of names done by the example code this is true.

Second, it requires that the client already have all of the suggestions for the shorter query. For this to be true the server must return more suggestions than the SuggestBox requests and there must be a way to decide if all possible suggestions have been returned. To do this the client asks for the server to return a number of suggestions that should, in most cases, include all possible suggestions. The server tries to return one more suggestion than the requested number so that the client can tell, by looking at the number returned, whether it has all suggestions. You can experiment with this in the example code by changing the numberOfServerSuggestions field in the ServerSuggestOracle class.

If the most recent data from the server can't satisfy the most recent client request then the code calls the server. When this returns successfully the results from the server are recorded and the returnSuggestions method is called to try and use these results to satisfy the most recent request from the SuggestBox, which may be a later request than the one that has just completed.

The downloadable example SuggestOracle code includes four different SuggestOracle implementations that can be easily run using hosted mode. When you run in hosted mode you may notice a short delay after the explanatory text appears before the SuggestBox fields themselves are visible while the Java code is compiled.

Leave a Reply