Spring MVC概述


Spring MVC框架是一個開源的Java平台,為開發強大的基於Java的Web應用程式提供全面的基礎架構支援非常容易和非常快速。

Spring框架最初由Rod Johnson撰寫,並於2003年6月根據Apache 2.0許可證首次發布。

本教學是基於2015年3月發布的Spring Framework版本4.1.6編寫的。

Spring web MVC框架提供了MVC(模型 - 檢視 - 控制器)架構和用於開發靈活和鬆散耦合的Web應用程式的元件。 MVC模式導致應用程式的不同方面(輸入邏輯,業務邏輯和UI邏輯)分離,同時提供這些元素之間的鬆散耦合。

  • 模型(Model)封裝了應用程式資料,通常它們將由POJO類組成。
  • 檢視(View)負責渲染模型資料,一般來說它生成用戶端瀏覽器可以解釋HTML輸出。
  • 控制器(Controller)負責處理使用者請求並構建適當的模型,並將其傳遞給檢視進行渲染。

DispatcherServlet元件類

Spring Web模型 - 檢視 - 控制器(MVC)框架是圍繞DispatcherServlet設計的,它處理所有的HTTP請求和響應。 Spring Web MVC DispatcherServlet的請求處理工作流如下圖所示:

以下是對應於到DispatcherServlet的傳入HTTP請求的事件順序:

  • 在接收到HTTP請求後,DispatcherServlet會查詢HandlerMapping以呼叫相應的Controller
  • Controller接受請求並根據使用的GETPOST方法呼叫相應的服務方法。 服務方法將基於定義的業務邏輯設定模型資料,並將檢視名稱返回給DispatcherServlet
  • DispatcherServlet將從ViewResolver獲取請求的定義檢視。
  • 當檢視完成,DispatcherServlet將模型資料傳遞到最終的檢視,並在瀏覽器上呈現。

所有上述元件,即: HandlerMappingControllerViewResolverWebApplicationContext的一部分,它是普通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.yiibai" />

   <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」的模型。
  • 定義的服務方法可以返回一個String,它包含要用於渲染模型的檢視的名稱。此範例將「hello」返回為邏輯檢視名稱。

建立JSP檢視

Spring MVC支援許多型別的檢視用於不同的表示技術。包括 - JSP,HTML,PDF,Excel工作表,XML,Velocity模板,XSLT,JSON,Atom 和 RSS 源,JasperReports等。但最常見的是使用JSPL編寫的JSP模板,這裡使用的是JSP模板,並在/WEB-INF/hello/hello.jsp中寫一個簡單的hello檢視:

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

這裡${message}是在Controller中設定的屬性。可以在檢視中顯示多個屬性。