I wanted to add AJAX to Spring MVC application. So, I did what most us do, go through the documentation or blog of the Spring Source. But, after playing around I didn't get it to work properly so here are some details that might save you some time.

After I follow the instructions in AJAX in Spring 3.0 I got some error "406 Not Accepted", so let's explain how to make it work:

Server Side

First you need to setup the actions/methods that the ajax client will call and provide that data in a request. In the server side we are going to use Spring MVC and reply using a JSON format.

1. You need the annotation <mvc:annotation-driven /> in your spring.xml or servelet-web-context.xml
2. Then, you need to create your controller action that will reply to the AJAX invocation. Let's see the following example. E.g. ProductController.java 

1
2
3
4
5
@RequestMapping (value="/itemdescription", method=RequestMethod.GET, headers="Accept=application/json")
public @ResponseBody Product getItemDescription(@RequestParam String id){
// code…
return yourProduct;
}

There are a couple of things to point out here. Notice the return @ResponseBody Product type. So, you need to create create a POJO (Plain java class with the data that you want to send along with it's getters and setters). E.g. Product.java. 

Also, notice the @ResponseBody annotation. This annotation allow you to translate the Product object into a JSON representation. But, this is not magic! and you need a couple of JARs to make it work (additionally to the annotation metined in step (1):

  1. http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-core-asl
  2. http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl

Use maven or download and place this JARs in the lib manually.

Client Side

On the client side, I'm using jQuery and the code looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var jqxhr = $.getJSON("/<your-servlet-name>/itemdescription?id=" + itemId, function(result) {
//res=jQuery.stringify(result);

if (result != null) {
$.each(result, function(key, value) {
if (key === "descr") {
descr.val(value);
userdescr.val(value);
}
});
} else {
descr.val("");
userdescr.val("");
}
})
// .success(function() { console.log("2nd function second success"); })
.error(function(XMLHttpRequest, textStatus, errorThrown) {
console.log("error " + textStatus + ": " + errorThrown);
})
// .complete(function() { console.log("complete"); });

There are some function there that are useful for debugging like printing out errors to the console and complete function. Notice also that $.getJSON is expenting the reponse in of a appplication/json type. So be sure that you have the "Accept=application/json" in your controller on the server side.

Finally you can customize the javascript fragment shown above and place it in your webpage (JSP, HTML,...) in a ready document. (Also, It was also useful for me to add a delay after the document ready function because otherwise it conflicted with dojo framework apply to the same component. But remove the timeout if you want to)

1
2
3
4
5
6
7
8
9
10
11
$(document).ready(function() {
console.log("document.ready");
setTimeout(function() {
$(_itemId).keyup(function() {
checkItemId($(_itemId).val(), $(_descr), $(_userdescr));
});
$(_itemId).blur(function() {
checkItemId($(_itemId).val(), $(_descr), $(_userdescr));
});
}, 100);
});

 

 That's all you need.

Troubleshooting

As mentioned before the spring mvc blog explain more in details each of the steps but lack some minor details that are key to make it work. I was getting "406 Not Accepted" because I didn't have the jackson jars that the @ResponseBody needs to convert java objects to JSON. And also you need to add the Accept Request header in the controller.

Using Firebug in Firefox is very tab Net > XHR you can see all your ajax request and reponses. Very useful for debugging. Hope this save you some time and frustration. Any question or suggestion fee free to comment below or contact me.