Stripes

Transparent AJAX form submission and validation using JSON

Details

Description

To support transparent integration of Stripes with JavaScript frameworks like jQuery, I've created a custom Stripes interceptor and resolution, plus some client-side JavaScript. What this allows JSP authors to do is bind a simple stripes() function to a form button element. The submission to Stripes is done using a background XHR, with all validation errors and redirects handled gracefully. The results look just like what you'd see with a full-page POST-and-render page cycle. And best of all, ActionBeans do not need to be re-written at all. Here's the basic flow:

1. The AjaxInterceptor intercepts the CustomValidation and EventHandling events. If the HTTP request does contains the header 'X-Requested-With,' and its value is 'XMLHttpRequest,' the request is assumed to be an AJAX request.

2. AjaxInterceptor calls proceed() to see if other interceptors (or lifecycle stages) have returned a non-null Resolution.

3. If the non-null Resolution is a RedirectResolution, it is wrapped by a JsonResolution whose .redirect property contains the URL the user should be directed to.

4. If the results of the bean processing generated validation errors or messages, a new JsonResolution is returned with its .fieldErrors, .globalErrors and .messages properties set appropriately. The contents of these properties are all localized Strings that are rendered identically to those output by the stripes:messages and stripes:errors tags. The locale is determined from the ActionBeanContext.

5. The JsonResolution is finally executed by the Stripes controller, it is converted into a JSON object and sent back to the client.

6. After the client receives the JSON response, error strings are injected into the HTML DOM. By default, messages are injected into the element named ${eventName}Messages, and global errors into ${eventName}Errors. Field errors, if these are rendered, are added to the right of input elements whose names attributes match the fields. For example, an error for field 'password' would be injected adjacent to the input named 'password.' The invalid input elements themselves have the class 'error' added, just like the Stripes tags do.

Requirements: the server-side code uses Jackson to marshal JSON output. The client Javascript assumes jQuery, although it could be readily adapted to other frameworks.

Key benefits:

  • Zero extra coding required for ActionBeans to support Ajax calls
  • Background submission of forms, with validation
  • Re-use of error and message headers, footers and before/after message and error formats, as defined in the Stripes localization bundle files

Activity

Hide
Nikolaos added a comment - 04/Mar/11 4:17 PM

This patch seems quite interesting as we are currently playing around with JSON in our application.

One thing that initially came up is that there is a class that is "not" included in the patch:

import org.ienroll.Configuration; // <== Missing class
...
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(servletContext);
Configuration config = ac.getBean(Configuration.class);
String baseUrl = config.getBaseUrl();

What exactly does this method do?

--Nikolaos

Show
Nikolaos added a comment - 04/Mar/11 4:17 PM This patch seems quite interesting as we are currently playing around with JSON in our application. One thing that initially came up is that there is a class that is "not" included in the patch: import org.ienroll.Configuration; // <== Missing class ... ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(servletContext); Configuration config = ac.getBean(Configuration.class); String baseUrl = config.getBaseUrl(); What exactly does this method do? --Nikolaos
Hide
Andrew Jaquith added a comment - 05/Mar/11 12:21 PM

Hi Nikolaos:

These methods relate to looking up some values in a class that is specific to my application. It shouldn't be there... I should have scrubbed this from the code first. You can safely remove these lines and still have full functionality.

Show
Andrew Jaquith added a comment - 05/Mar/11 12:21 PM Hi Nikolaos: These methods relate to looking up some values in a class that is specific to my application. It shouldn't be there... I should have scrubbed this from the code first. You can safely remove these lines and still have full functionality.

People

Vote (0)
Watch (0)

Dates

  • Created:
    23/Feb/11 9:09 PM
    Updated:
    05/Mar/11 12:21 PM