Spring MVC是一种基于Java的MVC框架,旨在简化Web应用程序的开发。在Spring MVC中,Controller 是调度基础视图渲染器的中心枢纽。在响应客户端请求时,Controller 通过ModelAndView(或 ModelMap)对象将数据传递给视图层。ModelAndView 是一种容器对象,它包含了数据模型和视图名。视图渲染器根据视图名找到实际的视图模板,并将数据模型提供给模板,生成HTML响应。本文将探讨如何使用 ModelAndView 在Spring MVC中展示视图并传递数据。
ModelAndView的工作原理
在Spring MVC中,Controller 方法作为请求处理方法。当DispatcherServlet检测到HTTP请求时,它调用适当的Controller方法将请求路由到方法中。Controller 方法执行后,需要向视图渲染器提供数据和视图名称。通常,我们使用ModelAndView对象处理此类需求。ModelAndView 对象包含两个主要的部分:The Model 和 View 名称。Model 是用于存储表示特定视图的数据的容器。View 名称是指要呈现的视图的名称。以下是一个典型的 ModelAndView 对象的实例:
```
@RequestMapping("/books")
public ModelAndView getBooks() {
ModelAndView mav = new ModelAndView("books.jsp");
List
mav.addObject("books", books);
return mav;
}
```
在此代码片段中,我们首先创建了一个 ModelAndView 对象,其视图名称为“books.jsp”。我们之后从数据访问对象(DAO)获取书籍列表,并将其添加到 Model 中作为一个名为“books”的属性。我们将 ModelAndView 对象作为请求处理方法的返回值,这样DispatcherServlet 就知道要使用我们指定的视图来呈现响应。
指定视图解析器
在上面的例子中,视图名称是硬编码的。在更大的应用程序中,我们不希望将视图名称硬编码在代码中。相反,我们将使用视图解析器。视图解析器会将逻辑视图名称映射到实际视图模板。在Spring MVC中,一般有两种类型的视图:InternalResourceView 和 JstlView。前者用于基于JSP的视图,而后者用于基于JSP标准标记库(JSTL)的视图。
我们可以在Spring配置中使用 ViewResolver bean 来设置视图解析器。以下是一个使用 InternalResourceViewResolver(基于 JSP 的视图)的例子:
```
@Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
```
此示例 Configuration 使用 viewResolver() 方法返回一个 InternalResourceViewResolver 对象。该对象设置了前缀和后缀,这些前缀和后缀将视图名称映射到JSP文件路径。在上述示例中,我们设置了JSP文件夹的前缀为 /WEB-INF/jsp/,后缀为 .jsp。假设我们要使用视图名称 books 来呈现一个视图。则我们定义了一个名为 /WEB-INF/jsp/books.jsp 的视图模板。视图解析器将在执行Handler方法后找到这个模板。
在另一个示例中,我们使用 JstlView 作为视图。要使用 JSTL 视图,我们需要添加 jstl 库到类路径中,以便引入 JSTL 标记库。以下是一个使用 JstlView 渲染视图的示例:
```
@Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Bean
public UrlBasedViewResolver urlBasedViewResolver() {
UrlBasedViewResolver urlBasedViewResolver = new UrlBasedViewResolver();
urlBasedViewResolver.setPrefix("/WEB-INF/jsp/");
urlBasedViewResolver.setSuffix(".jsp");
urlBasedViewResolver.setViewClass(JstlView.class);
return urlBasedViewResolver;
}
}
```
在上面的代码中,我们定义了一个 UrlBasedViewResolver bean,其配置类似于 InternalResourceViewResolver 配置。但是,我们使用了 JstlView.class 作为视图解析器的视图类类型。这将指示视图解析器使用 JSTL 标记库作为视图语言渲染视图。
使用Model传递数据
在Spring MVC中,Controller方法通过 Model 向视图传递数据。Model是一个容器对象,用于存储与请求处理方法相关的数据。Model interface身上继承了Map接口和提供一些诸如addAttribute和getAttribute等方法,这些方法允许添加和检索模型属性。
以下是一个使用Model传递数据的典型示例:
```
@RequestMapping("/books")
public String getBooks(Model model) {
List
model.addAttribute("books", books);
return "books";//视图名称
}
```
在此代码片段中,我们从数据访问对象获取书籍列表,并将其添加到 Model中。Model.addAttribute() 方法用于将数据添加到 Model 对象中。该方法接受两个参数,属性名称和属性值。在上面的示例中,我们将属性名books,值为List
使用ModelAttribute接收数据
在Spring MVC中,@ModelAttribute 注释用于声明入站数据绑定源。它旨在通过将请求参数中的值绑定到对象及其字段中来支持表单处理。在以下示例中,@ModelAttribute 注释用于接收名为bookId的查询字符串参数:
```
@RequestMapping(value = "/books", method = RequestMethod.GET)
public ModelAndView getBookById(@ModelAttribute("bookId") Long bookId) {
ModelAndView mav = new ModelAndView("book.jsp");
Book book = bookService.getBookById(bookId);
mav.addObject("book", book);
return mav;
}
```
在以上代码中,@ModelAttribute("bookId") Long bookId 注释将 name bookId 将入站请求参数绑定到它所注释的处理方法参数。在上面的示例中,QueryString中的bookId值传递给getBookById 方法的bookId参数。
在以上示例中,当我们使用 Model 时,我们必须定位要添加数据的 Model 属性名。与此不同,@ModelAttribute 注释允许我们使用参数名称直接将表单数据绑定到方法参数。在使用@ModelAttribute 注释时,Spring MVC会自动为我们执行数据绑定。
在Spring MVC中,@ModelAttribute 注释还可以用于声明返回值会添加到 Model 的属性。在以下示例中,我们使用@ModelAttribute("books") 注释声明 getBooks() 方法返回值将被添加到“books”属性中。
```
@ModelAttribute("books")
public List
return bookService.getBooks();
}
```
已经在@ModelAttribute 注释中添加的属性不需要出现在 ModelAndView 中。它将传递给每个使用返回的那个视图对象。
结论
Spring MVC中的 ModelAndView 提供了一种将模型和视图名称捆绑在一起的方式,并将它们传递给呈现 HTML 响应的处理程序。Spring MVC 还为开发人员提供了多种视图解析器,以灵活地将逻辑视图名称映射到实际视图模板。通过使用 Model 和 @ModelAttribute 内置对象,可以方便地在Spring MVC中传递和绑定表单数据。了解这些常用的功能后,就可以在开发Web应用程序时更有效地使用Spring MVC。