原文: http://zetcode.com/spring/modelandview/

Spring ModelAndView教程展示了如何在 Spring Web 应用的控制器中使用ModelAndView

Spring 是用于创建企业应用的流行 Java 应用框架。

ModelAndView

ModelAndView是 Web MVC 框架中ModelView的持有者。 这两类是截然不同的。 ModelAndView仅保留两者,以使控制器有可能在单个返回值中返回模型和视图。

该视图由ViewResolver对象解析; 该模型是存储在Map中的数据。

Spring ModelAndView示例

以下应用使用ModelAndView在 Spring 控制器中一步返回模型和视图。 我们使用 Freemarker 进行视图解析。

  1. pom.xml
  2. src
  3. ├───main
  4. ├───java
  5. └───com
  6. └───zetcode
  7. ├───config
  8. MyWebInitializer.java
  9. WebConfig.java
  10. └───controller
  11. MyController.java
  12. └───resources
  13. logback.xml
  14. └───templates
  15. index.ftl
  16. show.ftl
  17. └───test
  18. └───java

这是项目结构。

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>com.zetcode</groupId>
  8. <artifactId>springmodelandview</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>war</packaging>
  11. <properties>
  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13. <maven.compiler.source>11</maven.compiler.source>
  14. <maven.compiler.target>11</maven.compiler.target>
  15. <spring-version>5.1.3.RELEASE</spring-version>
  16. </properties>
  17. <dependencies>
  18. <dependency>
  19. <groupId>ch.qos.logback</groupId>
  20. <artifactId>logback-classic</artifactId>
  21. <version>1.2.3</version>
  22. </dependency>
  23. <dependency>
  24. <groupId>javax.servlet</groupId>
  25. <artifactId>javax.servlet-api</artifactId>
  26. <version>4.0.1</version>
  27. <scope>provided</scope>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.springframework</groupId>
  31. <artifactId>spring-context-support</artifactId>
  32. <version>5.1.3.RELEASE</version>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.springframework</groupId>
  36. <artifactId>spring-webmvc</artifactId>
  37. <version>5.1.3.RELEASE</version>
  38. </dependency>
  39. <dependency>
  40. <groupId>org.freemarker</groupId>
  41. <artifactId>freemarker</artifactId>
  42. <version>2.3.28</version>
  43. </dependency>
  44. </dependencies>
  45. <build>
  46. <plugins>
  47. <plugin>
  48. <groupId>org.apache.maven.plugins</groupId>
  49. <artifactId>maven-war-plugin</artifactId>
  50. <version>3.2.2</version>
  51. </plugin>
  52. <plugin>
  53. <groupId>org.eclipse.jetty</groupId>
  54. <artifactId>jetty-maven-plugin</artifactId>
  55. <version>9.4.14.v20181114</version>
  56. </plugin>
  57. </plugins>
  58. </build>
  59. </project>

pom.xml中,我们具有必要的依赖项。

resources/logback.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration>
  3. <logger name="org.springframework" level="ERROR"/>
  4. <logger name="com.zetcode" level="INFO"/>
  5. <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
  6. <encoder>
  7. <Pattern>%d{HH:mm:ss.SSS} %blue(%-5level) %magenta(%logger{36}) - %msg %n
  8. </Pattern>
  9. </encoder>
  10. </appender>
  11. <root>
  12. <level value="INFO" />
  13. <appender-ref ref="consoleAppender" />
  14. </root>
  15. </configuration>

logback.xml是 Logback 日志库的配置文件。

com/zetcode/config/MyWebInitializer.java

  1. package com.zetcode.config;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
  4. @Configuration
  5. public class MyWebInitializer extends
  6. AbstractAnnotationConfigDispatcherServletInitializer {
  7. @Override
  8. protected Class<?>[] getRootConfigClasses() {
  9. return null;
  10. }
  11. @Override
  12. protected Class<?>[] getServletConfigClasses() {
  13. return new Class[]{WebConfig.class};
  14. }
  15. @Override
  16. protected String[] getServletMappings() {
  17. return new String[]{"/"};
  18. }
  19. }

MyWebInitializer注册 Spring DispatcherServlet,它是 Spring Web 应用的前端控制器。

  1. @Override
  2. protected Class<?>[] getServletConfigClasses() {
  3. return new Class[]{WebConfig.class};
  4. }

getServletConfigClasses()返回 Web 配置类。

com/zetcode/config/WebConfig.java

  1. package com.zetcode.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.ComponentScan;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.web.servlet.config.annotation.EnableWebMvc;
  6. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  7. import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
  8. import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
  9. @Configuration
  10. @EnableWebMvc
  11. @ComponentScan(basePackages = {"com.zetcode"})
  12. public class WebConfig implements WebMvcConfigurer {
  13. @Bean
  14. public FreeMarkerViewResolver freemarkerViewResolver() {
  15. var resolver = new FreeMarkerViewResolver();
  16. resolver.setCache(true);
  17. resolver.setSuffix(".ftl");
  18. return resolver;
  19. }
  20. @Bean
  21. public FreeMarkerConfigurer freemarkerConfig() {
  22. var freeMarkerConfigurer = new FreeMarkerConfigurer();
  23. freeMarkerConfigurer.setTemplateLoaderPath("classpath:/templates/");
  24. return freeMarkerConfigurer;
  25. }
  26. }

WebConfig配置 FreeMarker 模板引擎。 我们将模板文件的位置设置为classpath上的templates目录。 (resources在类路径上。)

com/zetcode/controller/MyController.java

  1. package com.zetcode.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.GetMapping;
  4. import org.springframework.web.servlet.ModelAndView;
  5. import java.time.LocalDateTime;
  6. import java.time.format.DateTimeFormatter;
  7. @Controller
  8. public class MyController {
  9. @GetMapping(value = "/")
  10. public String home() {
  11. return "index";
  12. }
  13. @GetMapping(value = "/show")
  14. public ModelAndView show() {
  15. var mav = new ModelAndView();
  16. var now = LocalDateTime.now();
  17. var formatter = DateTimeFormatter.ISO_DATE_TIME;
  18. var dateTimeFormatted = formatter.format(now);
  19. mav.addObject("now", dateTimeFormatted);
  20. mav.setViewName("show");
  21. return mav;
  22. }
  23. }

MyController提供了两个 GET 映射。

  1. @GetMapping(value = "/show")
  2. public ModelAndView show() {

show()方法返回ModelAndView

  1. var mav = new ModelAndView();
  2. var now = LocalDateTime.now();
  3. var formatter = DateTimeFormatter.ISO_DATE_TIME;
  4. var dateTimeFormatted = formatter.format(now);
  5. mav.addObject("now", dateTimeFormatted);
  6. mav.setViewName("show");
  7. return mav;

创建一个ModelAndView并填充数据。 数据是格式化的日期时间对象。 视图名称由setViewName()设置。 Spring 将视图名称解析为show.ftl

resources/templates/index.ftl

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Home</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. </head>
  8. <body>
  9. <p>
  10. <a href="show">Show today's datetime</a>
  11. </p>
  12. </body>
  13. </html>

主页包含一个链接,以显示今天的日期时间。

resources/templates/show.ftl

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Today's date</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. </head>
  8. <body>
  9. <p>
  10. Today is: ${now}
  11. </p>
  12. </body>
  13. </html>

show.ftl视图中,我们使用${}语法显示当前日期时间。

  1. $ mvn jetty:run

我们运行服务器并找到localhost:8080以获取具有链接的主页。

在本教程中,我们使用ModelAndView来组织模型和视图。

您可能也对这些相关教程感兴趣: Spring @Configuration教程Spring @GetMapping教程Java 教程或列出所有 Spring 教程