HttpRedirectFilter. While this filter worked well using the GAE SDK, I ran into problems connecting to google's remote hosts. In particular, the filter was returning 302 status codes (Temporarily Moved) on the redirect, which AJAX will not treat as a successful outcome (AJAX requires 200-series status codes for successful responses). Instead, I decided to simply write my own filter based on similiar design outlined in the book "GWT Web Toolkit Applications" written by Ryan Dewsbury (ISBN-13: 978-0-321-50196-7). While this book is written against GWT 1.4 (and prior) it is a great reference for developing applications for GWT. There may be newer editions of the book and I would recommend it it.
If there is interest in the filter, I suppose I could post it to the blog or a source repository as open-source under Apache 2.0 License. I did run into a few tricks that go beyond what is highlighted in the GWT book which are worth noting (some are specific to forwarding to GAE, some are general "advanced" WEB related)
- GZIP encoding. If the response from the host (GAE or other) has a
Content-Encodingheader set containing
gzipyou will need to use a
GZIPInputStream( )to parse the input or error streams from the response. By default, the GAE SDK was not returning GZIP output, and my results were fine, until I ported my python app to GAE servers. At this point the response came back in
gzipthus resulting in garbage data without the
- The proxy as defined in the book proxies from Source A to Host B. In my case, I wanted some more advanced functionality (like mapping partial or complete URIs to a new URL) so implemented a simple
redirectMappings.xmlproperty file to do this. For example, in a Restful Web application, you might have a resource path like
- The example proxy does not encode the form data in the proxy (and assumes you are encoding it in your client under a "post" attribute). My approach was to treat the requests from GWT no different than any application request, so any values like method, FORM data should be encoded into the headers/parameters rather than having the proxy except some specialized structure of data. This makes the proxy "benign" in nature and it also means that it does not really matter if the proxy is there or not (from the client side).
- FORM data should only be added if the request is a
DELETErequest. (although in REST, the
DELETEshould be a path variables on the URI) GAE will return a status code of 500 if the
GETrequest contains FORM data.
- GAE will reject requests which contain certain headers. I have had difficulty getting information from the Google site on this, but from the discussion forums (as well as my testing) requests which contain the following were rejected:
/resources/preferences/categories/currencywhere the resource is
preferencesand the remaining URI values are directing the request (in this case getting all preferences with the currency category). Ideally you do not want your mapping to be setup against all possible URIs, but only the resource path (
/resources/preferencesin this case) appending the remaining URI path to this redirected URL.
I also thought I should make a brief commentary on the overhead associated with using a servlet filter for redirects. It would appear that using the filter imposes ~ 400-500 ms overhead per request. This is probably not a big deal on development systems, but obviously I would not recommend this for production. My suggestive approach in this article (and former) are really meant to be used for a developer to build an application concurrently with GWT (using the Hosted Mode browser) in conjunction with the GAE SDK (or even hosted server(s)). This eliviates the pain of having to have a fully functioning service/server prior to developing the client and allows each to be developed concurrently making a much cleaner development experience (especially if you are like me and doing this as a hobby).