AJAX is something that you must have been living under a rock if you haven't heard of before now, so I'm not going to do the "this is what AJAX is" routine. If you need that, I'd suggest you go here. Since AJAX is very much a client-side technology, and Stripes is a server side framework, this document will mainly focus on how to interact with Stripes using AJAX technologies. If you're looking for neat visual effects and general AJAX tips, you'd be better off searching google!
This "How To" will walk through:
- How to invoke Stripes ActionBeans using AJAX
- An AJAX version of the Calculator application from the Quick Start Guide
- Some additional techniques for using AJAX with Stripes
Although the calculator application is somewhat trivial, it serves as a good example for how to use Stripes with AJAX. The following is the JSP from the Quick Start Guide modified a little (if you haven't read the quick start, you might want to at least take a look at the example code for comparison):
There are a few changes to note. Working from the bottom up, we see:
In this case, we no longer insert the result from the ActionBean using EL, because the result isn't rendered into the JSP on the server side. Instead the place where the result will go is identified by an id so that we can reference it after the page has loaded. Next we see:
That's it for the JSP. Assuming we have everything setup for the ActionBean to work right, the page will contact the server when a button is clicked and render the response into the page without refreshing the browser window.
Let's take a look at the ActionBean:
This looks very similar to the code from the quickstart example, other than the implementations of add and divide. Instead of setting an attribute on the ActionBean and forwarding the user to a JSP, the handler methods now perform the calculation and then simply sends the result back to the client as text using a StreamingResolution:
That's it for the basics. Our page will now contact our ActionBean when one of the buttons is hit, and the result will get transferred back to the page and displayed in the appropriate place.
This all works great, until some validation errors occur. Then Stripes tries to forward the user back to the page that originated the request and render it with errors. With the code shown above, this results in the page getting embedded in itself! Oops. Luckily there is a way to handle this. Stripes provides an optional interface for ActionBeans called ValidationErrorHandler. This allows ActionBeans to intercept the flow of execution when validation errors occur, and tell Stripes what to do next.
At the top of our ActionBean we can add:
Because the ActionBean implements ValidationErrorHandler Stripes will invoke the handleValidationErrors method if any validation errors are generated. In this case the method loops through the set of errors constructing an HTML fragment with each error in a separate div. This is then returned to the client, again using the StreamingResolution. Now when validation errors occur they are displayed in the same place that the result would be displayed.
The StreamingResolution works well when:
- you are streaming data back to the client from a stream or reader object (e.g. streaming back a chunk of XML received from a web service invocation or the database)
- you are generating a few kilobytes or less of information, programmatically in your ActionBean
If, however, you are generating a lot of output from your ActionBean and do not want to buffer it entirely to a String before starting to send it back to the client, one good way to approach the problem is to create an anonymous Resolution. Take a look at the following example:
If your ajax request expects an html fragment as a response, you can use a ForwardResolution to generate it. The benefit to this is that the html is created by a jsp.
- Ajax.Updater makes a request
- Your ActionBean event handler forwards to a jsp
- Ajax.Updater updates $(container) with whatever html fragment the jsp renders
For example, if we ever decide to add a button to our calculator to reveal a hidden drawer containing additional functionality, we could create an event handler 'showScientificCalc()' and add a new jsp 'scientificCalcControls.jsp'.
In some situations you may want to return structured data to the browser instead of HTML for display. In general there are two ways to do this:
- return an XML island containing your data