Spring Setup
Spring requires very little setup. Provided the Jackson classes are on the classpath<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.7</version>
<scope>compile</scope>
</dependency>
Then spring is basically ready to go!
Returning JSON
Returning JSON to the client is the easiest part. Just return a class or list of classes from the spring MVC controller method and it will be transformed into JSON automagically and be available to the client. The key piece of magic here is the @ResponseBody tag which tells spring that the return value should make up the whole of the response body of the Http Response. Also the produces = .. value tells spring to use the Jackson processor because we can the application/json mime type as the output.Here is an example
@RequestMapping(value = "/gettopics", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public List<String> getTopics(final HttpServletRequest request)
{
final List<String> topics = new ArrayList<String>();
topics.add("topic1");
topics.add("topic2");
return topics;
}
Here the topics List object gets changed to a javascript list. This can be processed on the client side by getting a result object
for (var i=0; i<result.length; i++){
alert(result[i]);
}
And that is basically it. Obviously your choice of javascript library to do the ajax request will have an impact here. JQuery or Dojo would be the most common.
Accepting JSON
Accepting an json object into a Spring MVC method is a little more tricky. Firstly you have to create an object to marshal into such aspublic class JsonExample {
/** Value 1. */
private final String value1;
/** Value 2. */
private final String value2;
/**
* Construct this object. The benefit here is that this object is now immutable.
*/
@JsonCreator
public JsonExample(@JsonProperty("value1") final String value1,
@JsonProperty("value2") final String value2){
this.value1 = value1;
this.value2 = value2;
}
/**
* Get the first value
@JsonCreator
public JsonExample(@JsonProperty("value1") final String value1,
@JsonProperty("value2") final String value2){
this.value1 = value1;
this.value2 = value2;
}
/**
* Get the first value
*/
public String getValue1(){
return value1;
}
}
The annotations here tell Jackson how to marshal the JSON into this java object. However, if you don't want an immutable object you just create getters and setters and you don't need any annotations at all! In the MVC controller method we simply have a @RequestBody rather than @ResponseBody this time and it all just works.
@RequestMapping(value = "/settopics", method = RequestMethod.POST)
@ResponseBody
public void setTopics(final HttpServletRequest request, @RequestBody final JsonExample jsonExample)
{
...
}
Here the @ResponseBody seems like it should be surplus to requirements but the client doesn't like it if it isn't there.
In the web client a Javascript object is created
var topics = {
value1 : 'my topic',
value2 : 'another topic'
};
var stringToSend = json.stringify(topics);
Again the choice of javascript library to make this call is down to the user but here the dojo/json module has been used. The content headers need to be set on the post request
Content-Type : 'application/json'
public class JsonExampleList extends ArrayList<JsonExample> {
private static final long serialVersionUID = 3412220511906097746L;
}
It doesn't require anything in it at all but helps Jackson sort out what you really mean and then the marshalling can continue. Without doing this Jackson will convert to a LinkedHashMap of values and you can process this manually if you want to but the tip above will help Jackson sort it out.
@RequestMapping(value = "/settopics", method = RequestMethod.POST)
@ResponseBody
public void setTopics(final HttpServletRequest request, @RequestBody final JsonExample jsonExample)
{
...
}
Here the @ResponseBody seems like it should be surplus to requirements but the client doesn't like it if it isn't there.
In the web client a Javascript object is created
var topics = {
value1 : 'my topic',
value2 : 'another topic'
};
var stringToSend = json.stringify(topics);
Again the choice of javascript library to make this call is down to the user but here the dojo/json module has been used. The content headers need to be set on the post request
Content-Type : 'application/json'
Posting a List of Objects
You would think that if you posted a list of object then you could just declare List<JsonExample> in the spring method but unfortunately this doesn't work. Instead you have to declare an extension to the List object such aspublic class JsonExampleList extends ArrayList<JsonExample> {
private static final long serialVersionUID = 3412220511906097746L;
}
It doesn't require anything in it at all but helps Jackson sort out what you really mean and then the marshalling can continue. Without doing this Jackson will convert to a LinkedHashMap of values and you can process this manually if you want to but the tip above will help Jackson sort it out.
No comments:
Post a Comment