活用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. 你可以进一步使用内容协商,来处理多语言,字符编码等问题。
当然也有不爽的,那就是你要写多个模板文件,这或许会让你觉得有点烦,这时候也许生成器是个好选择。