在Spring MVC中处理多种内容类型...首选哪种方法?

时间:2010-12-09 23:29:40

标签: java spring spring-mvc

因此,我们在Spring应用程序中已经到了这一点,我们需要决定如何处理视图和内容协商。以前,我们只支持端点中的一种特定内容类型。

我将抛​​出我认为的三种方法。

我的问题:哪一项通常被认为是最佳做法/维护量最少?我们的目标是在我们的应用程序中遵循一个坚实的惯例,如果需要,可以在需要时提供灵活性。

第一种方法:
使用ContentNegotiatingViewResolver。这将涉及在servlet文件中定义的映射...在控制器中,每个控制器操作都需要使用一些魔术字符串在地图中显式设置对象。控制器操作将返回一个字符串,该字符串引用模板名称...类似于以下内容:

@RequestMapping(value = "/someMapping/source", method = RequestMethod.GET)
public String foo(Model model)
{
    // more stuff here
    model.addAttribute(SOME_MODEL_KEY, new ArrayList<String>() { "hello world"});

    return "someDummyJsonString";
}

缺点:
查看解析器看起来有点笨拙......它们有优先级,你需要经常覆盖它们等等。另外,我不喜欢用于引用模板/视图bean名称的“魔术字符串”的想法。

第二种方法:
我认为这是Spring 3.0中的新功能,但在RequestMapping中你可以匹配标题...所以你可以在Accept标题上匹配,如下所示:

@RequestMapping(value="/someMapping", method = RequestMethod.GET, headers="Accept=application/json")
public @ResponseBody SomeBar foo() 
{
  // call common controller code here
  return buildBar();
}

@RequestMapping(value="/someMapping", method = RequestMethod.GET, headers="Accept=text/xml")
public String foo(Model model) 
{
  model.addAttribute("someModelName", this.buildBar()); 
  return "someTemplateNameProcessedByViewResolver";
}

SomeBar buildBar() 
{
   return new SomeBar();
}

缺点:
可能不够灵活吗?我不确定,但我认为我非常喜欢headers方法...我已经看到其他框架(RESTLet,Rails)使用类似的东西。

第三种方法:
第三种方法涉及创建一个自定义View,它将根据Accept标头协商内容,并通过适当的方法抛出模型。此内容协商视图必须知道模板,并加载模板等。

@RequestMapping(value="/someMapping", method = RequestMethod.GET, headers="Accept=text/xml")
public View foo() 
{
  SomeBar bar = new SomeBar();
  ContentNegotiatingView view = new ContentNegotiatingView(bar, "templateName");

  return return view;
}

缺点:
在这种情况下,视图似乎做得太多了...视图将查看标题,并设置响应主体本身。它可能还需要设置http状态。

所以,对不起文字的墙,让我知道你对此的看法。感谢

1 个答案:

答案 0 :(得分:2)

其他人只是asked this。请参阅my answer