Spring - MVC 框架概述


Spring Web MVC 框架提供了模型-视图-控制器架构和现成的组件,可用于开发灵活且松散耦合的 Web 应用程序。MVC 模式导致分离应用程序的不同方面(输入逻辑、业务逻辑和 UI 逻辑),同时在这些元素之间提供松散耦合。

  • 模型封装了应用程序数据,通常它们由POJO组成。

  • 视图 负责渲染模型数据,一般来说,它生成客户端浏览器可以解释的HTML输出。

  • 控制器负责处理用户请求构建适当的模型并将其传递给视图进行渲染。

调度程序Servlet

Spring Web 模型-视图-控制器 (MVC) 框架是围绕处理所有 HTTP 请求和响应的 DispatcherServlet 设计的。Spring Web MVC DispatcherServlet 的请求处理工作流程如下图所示。

Spring DispatcherServlet

以下是与 DispatcherServlet 传入 HTTP 请求相对应的事件序列 -

  • 收到 HTTP 请求后,DispatcherServlet 查阅HandlerMapping来调用适当的 Controller。

  • 控制器接受请求并根据使用的GETPOST 方法调用适当的服务方法。服务方法将根据定义的业务逻辑设置模型数据,并将视图名称返回给 DispatcherServlet。

  • DispatcherServlet 将借助ViewResolver来获取为请求定义的视图。

  • 一旦视图完成,DispatcherServlet 就会将模型数据传递给视图,最终在浏览器上呈现该视图。

所有上述组件,即 HandlerMapping、Controller 和 ViewResolver 都是WebApplicationContext的一部分,WebApplicationContext 是普通ApplicationContext的扩展,具有 Web 应用程序所需的一些额外功能。

所需配置

我们需要通过使用web.xml文件中的 URL 映射来映射您希望 DispatcherServlet 处理的请求。以下是显示HelloWeb DispatcherServlet 的声明和映射的示例 -

<web-app id = "WebApp_ID" version = "2.4"
   xmlns = "http://java.sun.com/xml/ns/j2ee" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee 
   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
   <display-name>Spring MVC Application</display-name>

   <servlet>
      <servlet-name>HelloWeb</servlet-name>
      <servlet-class>
         org.springframework.web.servlet.DispatcherServlet
      </servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>

   <servlet-mapping>
      <servlet-name>HelloWeb</servlet-name>
      <url-pattern>*.jsp</url-pattern>
   </servlet-mapping>
</web-app>

web.xml文件将保存在Web 应用程序的WebContent/WEB-INF目录中。HelloWeb DispatcherServlet初始化后,框架将尝试从位于应用程序的 WebContent/WEB-INF 目录中名为[servlet-name]-servlet.xml的文件加载应用程序上下文。在本例中,我们的文件将为HelloWeb-servlet.xml

接下来,<servlet-mapping>标记指示哪些 URL 将由哪个 DispatcherServlet 处理。在这里,所有以 .jsp 结尾的 HTTP 请求都将由HelloWeb DispatcherServlet处理。

如果您不想使用默认文件名[servlet-name]-servlet.xml和默认位置 WebContent/WEB-INF,则可以通过在 web.xml 中添加 servlet 侦听器ContextLoaderListener来自定义此文件名和位置文件如下 -

<web-app...>

   <!-------- DispatcherServlet definition goes here----->
   ....
   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/HelloWeb-servlet.xml</param-value>
   </context-param>

   <listener>
      <listener-class>
         org.springframework.web.context.ContextLoaderListener
      </listener-class>
   </listener>
</web-app>

现在,让我们检查HelloWeb-servlet.xml文件所需的配置,该文件位于 Web 应用程序的 WebContent/WEB-INF 目录中。

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:context = "http://www.springframework.org/schema/context"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "
   http://www.springframework.org/schema/beans     
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/context 
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:component-scan base-package = "com.tutorialspoint" />

   <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name = "prefix" value = "/WEB-INF/jsp/" />
      <property name = "suffix" value = ".jsp" />
   </bean>

</beans>

以下是有关HelloWeb-servlet.xml文件的一些要点-

  • [servlet-name]-servlet.xml文件将用于创建定义的 bean,覆盖全局范围内使用相同名称定义的任何 bean 的定义。

  • <context:component-scan...>标签将用于激活 Spring MVC 注解扫描功能,该功能允许使用@Controller@RequestMapping等注解。

  • InternalResourceViewResolver将定义用于解析视图名称的规则根据上面定义的规则,名为hello的逻辑视图被委托给位于/WEB-INF/jsp/hello.jsp的视图实现。

现在让我们了解如何创建实际的组件,即控制器、模型和视图。

定义控制器

DispatcherServlet 将请求委托给控制器以执行特定于它的功能。@Controller注释指示特定类充当控制器角色。@RequestMapping注释用于将 URL 映射到整个类或特定的处理程序方法

@Controller
@RequestMapping("/hello")
public class HelloController{
 
   @RequestMapping(method = RequestMethod.GET)
   public String printHello(ModelMap model) {
      model.addAttribute("message", "Hello Spring MVC Framework!");
      return "hello";
   }

}

@Controller注释将该类定义为 Spring MVC控制器。这里, @RequestMapping的第一次使用表明该控制器上的所有处理方法都相对于/hello路径。

下一个注释@RequestMapping (method = RequestMethod.GET)用于声明printHello()方法作为控制器的默认服务方法来处理 HTTP GET 请求。我们可以定义另一个方法来处理同一 URL 上的任何 POST 请求。

我们还可以以另一种形式编写上述控制器,我们可以在 @RequestMapping 中添加其他属性,如下所示 -

@Controller
public class HelloController{
 
   @RequestMapping(value = "/hello", method = RequestMethod.GET)
   public String printHello(ModelMap model) {
      model.addAttribute("message", "Hello Spring MVC Framework!");
      return "hello";
   }

}

value属性指示处理程序方法映射到的 URL,method属性定义处理 HTTP GET 请求的服务方法。

以下是关于上面定义的控制器需要注意的一些要点 -

  • 您将在服务方法内定义所需​​的业务逻辑。您可以根据需要在该方法中调用另一个方法。

  • 根据定义的业务逻辑,您将在此方法中创建一个模型。您可以设置不同的模型属性,视图将访问这些属性来呈现结果。此示例创建一个具有属性“message”的模型。

  • 定义的服务方法可以返回一个字符串,其中包含用于呈现模型的视图的名称。此示例返回“hello”作为逻辑视图名称。

创建 JSP 视图

Spring MVC 支持不同表示技术的多种类型的视图。其中包括 - JSP、HTML、PDF、Excel 工作表、XML、Velocity 模板、XSLT、JSON、AtomRSS feed、JasperReports等。但是,最常见的是用 JSTL 编写的 JSP 模板。因此,让我们在 /WEB-INF/hello/hello.jsp 中编写一个简单的 hello 视图 -

<html>
   <head>
      <title>Hello Spring MVC</title>
   </head>
   <body>
      <h2>${message}</h2>
   </body>
</html>

这里${message}这是我们在控制器中设置的属性。您可以在视图中显示多个属性。