欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

活用SpringMVC+Freemarker实现http内容协商 博客分类: j2ee frmework springmvcfreemarkerhttpcontent negociation

程序员文章站 2024-03-16 19:24:16
...

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. 你可以进一步使用内容协商,来处理多语言,字符编码等问题。

 

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