Spring MVC 控制器返回类型

Posted

技术标签:

【中文标题】Spring MVC 控制器返回类型【英文标题】:Spring MVC Controllers Return Type 【发布时间】:2011-09-12 05:23:50 【问题描述】:

我见过控制器返回字符串(表示视图)的示例

@RequestMapping(value="/owners/ownerId", method=RequestMethod.GET)
public String findOwner(@PathVariable String ownerId, Model model) 
  Owner owner = ownerService.findOwner(ownerId);  
  model.addAttribute("owner", owner);  
  return "displayOwner"

我还看到了控制器返回“ModelAndView”对象类型的示例

public ModelAndView helloWorld() 
    ModelAndView mav = new ModelAndView();
    mav.setViewName("helloWorld");
    mav.addObject("message", "Hello World!");
    return mav;

这两者有什么区别,我应该使用哪个?因为无论哪种方式,我都可以解决我的观点。

【问题讨论】:

我们说的是哪个版本的spring mvc? 这是答案:***.com/questions/29365833/… 【参考方案1】:

逻辑相同,但不是同一个版本的spring。

ModelAndView 对象是 spring 2.x 处理模型和视图的方式。 在您给出的示例中,modelandview 对象将加载“helloWorld”视图(取决于您的模板引擎可能是 helloWorld.jsp 或 helloWorld.html,...),模型中有一个数据“消息”。

另一种方式是spring 3.x方式。您可以编写与您的 helloworld 完全相同的示例。

@RequestMapping(value="/helloWorld", method=RequestMethod.GET)
public String helloWorld(Model model) 
    model.addAttribute("message", "Hello World!");
    return "helloWorld";

模型会根据请求自动填充。

我们可以简化这种表示法,因为 url 映射“helloWorld”直接是视图名称。

@RequestMapping(value="/helloWorld", method=RequestMethod.GET)
public void helloWorld(Model model) 
     model.addAttribute("message", "Hello World!");

helloWorld 视图将被自动加载

【讨论】:

【参考方案2】:

如果我们谈论的是 MVC 3,那么两者都是正确的。但是直接返回 ModelAndView 是老办法,而且比较口头。

如果你只返回一个字符串(没有 @ResponseBody 这是别的东西),这个字符串被视为视图名称,并且 spring 将它推送到视图解析器 - 所以,你不必担心(至少,当你编写控制器),你将使用什么类型的视图渲染器(让它是jsp或velocity,没关系)。您只传播Model 实例,并返回提示下一步如何处理它。适当的ModelAndView 对象稍后在内部由字符串生成。

一般来说,spring 3 在参数和返回类型方面为您提供了更大的灵活性(请参阅 Spring 文档中的 Defining @RequestMapping handler methods 部分)。

【讨论】:

在较新的 MVC 3 方法中(返回 String),Model 实例如何进入视图?在控制器中我们使用model.addAttribute(..)添加属性但最终只返回String,那么视图解析器是如何知道Model对象的呢?谢谢! 我相信它是由 RequestMapping 完成的某种依赖注入(即模型是由解析器提供给你的) - 但老实说,我不确定,因为我没有与 Spring 联系过那些过去5年^^【参考方案3】:

在Spring MVC中,如果要渲染jsp页面,应该返回ModelAndView

例如:

@RequestMapping(value="/index.html", method=RequestMethod.GET)
    public ModelAndView indexView()
        ModelAndView mv = new ModelAndView("index");
        return mv;
        

当你点击 /index.html 时,这个函数会返回 index.jsp

此外,您还可以使用 @ResponseBody 注释和序列化器返回任何 JSON 或 XML 对象。

例如:

@RequestMapping(value="/getStudent.do",method=RequestMethod.POST)
    @ResponseBody
    public List<Student> getStudent(@RequestParam("studentId") String id)
        List<Student> students = daoService.getStudent(id);
        return students;
    

在此示例中,您将以 JSON 形式返回 List,以防万一您启用了 Jackson 序列化程序。为了启用它,您需要将以下内容添加到您的 Spring XML:

<context:annotation-config/> 

还有序列化器本身:

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
  <list>
    <ref bean="jacksonMessageConverter"/>
  </list>
</property>
</bean>

希望对你有帮助。

【讨论】:

不需要直接创建并返回MAV。除此之外,如果您使用context:annotation-config,则不必手动放置序列化程序,如果jackson 在类路径上,它会自动完成。 完美,简单的例子非常有用。【参考方案4】:

返回 ModelAndView 或字符串执行相同的工作。它解析为视图(jsp 页面)并提供要在视图中呈现的模型对象。如果返回一个字符串,spring 会在内部使用 viewResolver 解析为一个视图,创建一个 ModelAndView 对象并返回它。 ModelAndView 对象的返回来自旧版本。您可以根据自己的方便进行任何一种操作。

看看这个question

还有一堆答案指向@RequestBody。它与您的问题并不完全相关。但请记住,它会使用可用的转换器根据内容类型转换您的对象,结果将成为文档正文的一部分。

【讨论】:

【参考方案5】:

如果您使用诸如 freemarker 或 velocity 之类的模板语言来创建响应,那么您可以返回 ModelAndView

如果您想返回一个 json/xml 或一些字符串作为响应(例如:ajax 请求),那么您可以使用第一种方法。我觉得应该是public @ResponseBody String findOwner(@PathVariable String ownerId, Model model),需要加一个叫@ResponseBody的注解,表示返回值要转换成响应文本。使用@ResponseBody 将使您能够使用Jackson 或JaxB 等库来分别创建json/xml 响应。

这些返回值将使用在AnnotationMethodHandlerAdapter注册的messageConverters进行转换。

参考:http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/

【讨论】:

你没有抓住重点。如果您定义了正确的view resolver,则返回的字符串将被视为视图名称(jsp、模板等)。 @ResponseBody 与此无关。 @AdamJurczyk 那么如果我已经定义了view resolver,我该如何使用@ResponseBody(我想为ajax调用返回JSON)?谢谢【参考方案6】:
public String findOwner(@PathVariable String ownerId, Model model) 
  Owner owner = ownerService.findOwner(ownerId);  
  model.addAttribute("owner", owner);  
  return "displayOwner"
                       

在这个方法中,返回类型是字符串,我们将模型添加为参数,因此要使用模型添加值,我们将添加类似

 modelparam.addAttribute("obj",value);  

并根据视图解析器返回显示所有者到jsp

public ModelAndView helloWorld() 
    ModelAndView mav = new ModelAndView();
    mav.setViewName("helloWorld");
    mav.addObject("message", "Hello World!");
    return mav;

在这个方法中,返回类型是 ModelAndView 所以我们将返回模型 这里的mav是ModelAndView的对象所以这里我们应该像这样添加

model.addObject("object","value");

这里viewname根据viewResolver返回到helloworld.jsp

【讨论】:

以上是关于Spring MVC 控制器返回类型的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC @Controller中返回值为void类型

Spring MVC @Controller中返回值为void类型

Spring MVC REST - 根据请求内容类型返回 xml 或 json

Spring mvc 实现jsonp和json数据类型

Spring企业级程序设计 • 第6章 深入Spring MVC开发

如何在 Spring MVC 中使用 AJAX 渲染视图