loading table of contents...

4.3.1.4. Handling Ajax Requests

Dealing with Ajax requests is quite simple when using the CAE together with Spring MVC features. The main difference of Ajax in comparison to "standard" request handling is the format of incoming and outgoing data. While standard requests typically provide an output format for end users such as HTML, Ajax requests mainly deal with machine readable formats like JSON and XML. The same applies to input formats: HTML based application have to deal with form input while Ajax request again make use of JSON/XML instead.

Spring MVC provides inbuilt converters for translating plain java beans ("POJOs") from/to XML or JSON. These converters can be easily used from within the CAE. When implementing an Ajax based handler, then no ModelAndView needs to be passed to the view engine but it is sufficient to provide the bean itself in conjunction with the @ResponseBody annotation.

Example

@RequestMapping(value = "/json/{id}", produces="application/json")
@ResponseBody
public MyPojo renderBeanAsJson(@PathVariable("id") String id) {
 MyPojo bean = getPojo(id);
 return bean;
}

In this example for an Ajax handler, a model bean is computed and simply returned as a "response body" rather than wrapping it into a ModelAndView. Due to the produces="application/json" attribute, the rendering engine knows that this bean should be automatically converted to JSON. This is internally done by recursively writing a JSON entry for all bean properties. When using produces="text/xml" instead, then the bean will be converted to XML as long as the bean's class is annotated with @javax.xml.bind.annotation.XmlRootElement.

The automatic conversion is done by instances of org.springframework.http.converter.HttpMessageConverters that need to be registered before usage:

<customize:append id="registerHttpMessageConverters" bean="httpMessageConverters">
  <list>
    <!-- converts request/response bodies from/to XML -->
    <bean class="org.springframework.http.converter.xml.
                  Jaxb2RootElementHttpMessageConverter"/>
    <!-- converts request/response bodies from/to JSON -->
    <bean class="org.springframework.http.converter.json.
                  MappingJacksonHttpMessageConverter"/>
  </list>
</customize:append>

The JSON converter MappingJacksonHttpMessageConverter requires the library jackson-mapper-asl which can be added to a Maven project like

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-mapper-asl</artifactId>
</dependency>

Handling POST Data

Writing a handler that handles incoming data (typically sent with a HTTP POST request and formatted as JSON or XML) can be implemented nearly the same way. The only thing that has to be done is to pass an @RequestBody annotated parameter to the handler method like

@RequestMapping(value="/json/{id}", method=RequestMethod.POST,
                consumes="application/json",
                produces="application/json")
@ResponseBody
public MyResultPojo renderBeanAsJson(
                             @PathVariable("id") String id,
                             @RequestBody MyIncomingPojo data) {

  MyResultPojo bean = processData(id, data);
  return bean;
}

Building Links

Implementing and buildings links for Ajax handlers works the same way as for all other resources. An example link scheme implementation:

@Link(type=MyPojo.class, view="json", uri="/json/{id}")
public UriComponents buildJsonLink(MyPojo bean,
                                   UriComponentsBuilder uri) {
  return uri.buildAndExpand(bean.getId());
}

A JavaScript snippet that can be embedded into a JSP might look like

<cm:link target="${myPojo}" view="json" var="pojoUrl"/>
<script type="text/javascript">
  var req = new XMLHttpRequest();
  req.open('GET', '${pojoUrl}', true);
  req.onreadystatechange = function() {
   // handle response ...
  };
  req.send();
</script>