Spring MVC 控制器返回类型

问题描述 投票:0回答:7

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

@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 spring-mvc
7个回答
19
投票

逻辑相同,但不是同一个版本的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 视图将自动加载


16
投票

如果我们谈论的是 MVC 3,那么,两者都是正确的。但直接返回ModelAndView是老方法了,而且更口语化。

如果您只返回一个字符串(没有@ResponseBody,这是其他东西),则该字符串被视为视图名称,并且 spring 将其推送到视图解析器 - 所以,您不必担心(至少,当您编写控制器时) ),您将使用什么类型的视图渲染器(让它是jsp或velocity,这并不重要)。您仅传播

Model
实例,并返回下一步如何处理它的提示。正确的
ModelAndView
对象稍后由字符串在内部创建。

通常,spring 3 为您提供了参数和返回类型的更大灵活性(请参阅 Spring 文档中的定义 @RequestMapping 处理程序方法部分)。


6
投票

在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 形式返回列表,以防万一并且您已启用 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>

希望有帮助。


6
投票

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

看看这个问题

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


1
投票

如果您使用 freemarker 或 Velocity 等模板语言来创建响应,那么您可以返回

ModelAndView

如果您想返回 json/xml 或某些字符串作为响应(例如:ajax 请求),那么您可以使用第一种方法。我觉得应该是

public @ResponseBody String findOwner(@PathVariable String ownerId, Model model)
,需要添加一个名为@ResponseBody的注解,表示将返回值转换为响应文本。使用
@ResponseBody
将使您能够使用 JacksonJaxB 等库分别创建 json/xml 响应。

这些返回值将使用注册到

messageConverters
AnnotationMethodHandlerAdapter
进行转换。

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


1
投票
public String findOwner(@PathVariable String ownerId, Model model) {
  Owner owner = ownerService.findOwner(ownerId);  
  model.addAttribute("owner", owner);  
  return "displayOwner"
}                       

在此方法中,返回类型是 String,我们添加 Model 作为参数,因此要使用 model 添加值,我们将添加如下

 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");

这里视图名称根据 viewResolver 返回到 helloworld.jsp


0
投票

春季6

除了返回任意类型的对象之外,

@GetMapping("/todos")
public List<Item> getTodos() {
    return repository.findAll();
}

您还可以返回

ResponseEntity
:

@GetMapping("/todos")
public ResponseEntity<List<Item>> getTodos() {
    return new ResponseEntity<>(repository.findAll(), HttpStatus.OK);
}

您还可以使用

ResponseEntity
构建器函数:

@GetMapping("/todos")
public ResponseEntity<List<Item>> getTodos() {
    return ResponseEntity.status(HttpStatus.OK).body(repository.findAll());
}

对于错误,你可以抛出一个

ResponseStatusException
:

@GetMapping("/todos")
public List<Item> getTodos() {
    boolean error = false;
    if (error){
        throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "There was an error!");
    }
    return repository.findAll();
}

或者您可以使用

ResponseEntity
构建器函数来处理错误:

@GetMapping("/todos")
public ResponseEntity<?> getTodos() {
    boolean error = false;
    if (error){
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("There was an error!");
    }
    return ResponseEntity.status(HttpStatus.OK).body(repository.findAll());
}

我正在使用 Spring 6.2.0 顺便说一句

© www.soinside.com 2019 - 2024. All rights reserved.