活用SpringMVC+Freemarker实现http内容协商

SpringMVC目前应用较广,Freemarker又是优秀的通用模板引擎,两者的结合十分方便。但既然是通用模板引擎,那么仅仅用来渲染Html页面未免暴殄天物。

如果我们从http request的header取得Accept值,并根据此值来选择不同的模板,渲染之,就能够达到http协议中的内容协商的目的了。

我们只需要一个类似下面的方法(这只是一个粗略实现,未考虑细节),即可以实现此模式。

public ModelAndView getTemplateByAcceptType(HttpServletRequest request,
			HttpServletResponse response, String template){
		String header_accept = request.getHeader("Accept").split(",")[0];
		ModelAndView mv ;
		if(header_accept.equalsIgnoreCase("application/json")){
			mv = new ModelAndView(template + ".json");
			response.setHeader("content-type", "application/json");
		}else if(header_accept.equalsIgnoreCase("application/xml")){
			mv = new ModelAndView(template + ".xml");
			response.setHeader("content-type", "application/xml");
		}
		else{
			mv = new ModelAndView(template + ".html");
			response.setHeader("content-type", "text/html");
		}
		return mv;
	}
 

那么,对应的,我们需要在同一个目录下提供多个模板文件, foo.json.ftl和foo.xml.ftl和foo.html.ftl。 

当然SpringMVC本身提供了一个@ResponseBody注释,通过使用 不同的wrapper也能够达到同样的目的,那这样做的好处是什么呢? 

1. 你可以使用同一个controller来处理不同的用户请求。

2. 可以不受Java方法返回值类型的限制,这意味着你可以更好的处理错误信息和异常等行为。

3. 你可以有选择的暴露想要返回给客户端的属性, 以及更灵活的处理对象间的嵌套,避免父子对象间的循环引用造成的序列化问题。

4. 你可以进一步使用内容协商,来处理多语言,字符编码等问题。

当然也有不爽的,那就是你要写多个模板文件,这或许会让你觉得有点烦,这时候也许生成器是个好选择。

相关推荐