Friday, March 28, 2008

Spring MVC JSON view

For Ajax-based web application, one of the most popular ways for message transfer is JSON (JavaScript Object Notation). JSON provides a pretty name/value pair data format which is easy to generate and parse.

With the popular using Spring framework. It would be really useful to integrate Spring MVC view with JSON. Spring already provides several view resolvers, which enable us to render models in a browser, such as: JSPs, Velocity templates and XSLT views.

To add JSON view to the Spring MVC, we need create a class: JSONView

public class JSONView implements View {
private static final String DEFAULT_JSON_CONTENT_TYPE = "application/json";
private static final String DEFAULT_JAVASCRIPT_TYPE = "text/javascript";
private JSONObject jsonObject;

public JSONView(JSONObject jsonObject) {
super();
this.jsonObject = jsonObject;
}

public JSONView() {
super();
this.jsonObject = null;
}

public String getContentType() {
return DEFAULT_JSON_CONTENT_TYPE;
}

public void render(Map model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
if (this.jsonObject == null) {
this.jsonObject = JsonUtil.fromMap(model);
}

boolean scriptTag = false;
String cb = request.getParameter("callback");
if (cb != null) {
scriptTag = true;
response.setContentType(DEFAULT_JAVASCRIPT_TYPE);
} else {
response.setContentType(DEFAULT_JSON_CONTENT_TYPE);
}

PrintWriter out = response.getWriter();
if (scriptTag) {
out.write(cb + "(");
}
out.write(this.jsonObject.toString());
if (scriptTag) {
out.write(");");
}
}
}

And this is fromMap function in JsonUtil

public static JSONObject fromMap(Map model) {
JSONObject jsonObject = new JSONObject();

try {
Iterator ite = model.keySet().iterator();
while (ite.hasNext()) {
String key = ite.next();
jsonObject.put(key, model.get(key));
}
} catch (Exception e) {
log.error("call fromMap failed ");
}

return jsonObject;
}

And in the controller side, we can pass JOSNObject to create a JSONView. Or we can also pass MAP to create JSONView.

Map map = new HashMap();
map.put("success", "true");
map.put("info", "Succeed create this audit object");
return new ModelAndView(new JSONView(), map);
OR

BaseSearchResult searchResult = auditService.getList(listAuditInfo);
AuditUtil auditUtil = new AuditUtil(searchResult);
return new ModelAndView(new JSONView(auditUtil.toJSONObject()));