我见过控制器返回字符串(表示视图)的示例
@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。
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 视图将自动加载
如果我们谈论的是 MVC 3,那么,两者都是正确的。但直接返回ModelAndView是老方法了,而且更口语化。
如果您只返回一个字符串(没有@ResponseBody,这是其他东西),则该字符串被视为视图名称,并且 spring 将其推送到视图解析器 - 所以,您不必担心(至少,当您编写控制器时) ),您将使用什么类型的视图渲染器(让它是jsp或velocity,这并不重要)。您仅传播
Model
实例,并返回下一步如何处理它的提示。正确的 ModelAndView
对象稍后由字符串在内部创建。
通常,spring 3 为您提供了参数和返回类型的更大灵活性(请参阅 Spring 文档中的定义 @RequestMapping 处理程序方法部分)。
在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>
希望有帮助。
返回 ModelAndView 或字符串可以完成相同的工作。它解析为视图(一个 jsp 页面)并提供要在视图中呈现的模型对象。如果返回一个字符串,spring内部会使用viewResolver解析为一个视图,创建一个ModelAndView对象并返回它。 ModelAndView对象的返回来自旧版本。您可以根据自己的方便进行其中任一操作。
看看这个问题
还有很多答案都指向@RequestBody。它与你的问题并不完全相关。但请记住,它将使用可用的转换器根据内容类型转换您的对象,并且结果将成为文档正文的一部分。
如果您使用 freemarker 或 Velocity 等模板语言来创建响应,那么您可以返回
ModelAndView
。
如果您想返回 json/xml 或某些字符串作为响应(例如:ajax 请求),那么您可以使用第一种方法。我觉得应该是
public @ResponseBody String findOwner(@PathVariable String ownerId, Model model)
,需要添加一个名为@ResponseBody的注解,表示将返回值转换为响应文本。使用 @ResponseBody
将使您能够使用 Jackson 或 JaxB 等库分别创建 json/xml 响应。
这些返回值将使用注册到
messageConverters
的 AnnotationMethodHandlerAdapter
进行转换。
参考:http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/
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
除了返回任意类型的对象之外,
@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 顺便说一句