1. 程式人生 > >Spring(十六之MVC框架

Spring(十六之MVC框架

req pos ase 返回 依賴 request best aps depend

MVC 框架教程

Spring web MVC 框架提供了模型-視圖-控制的體系結構和可以用來開發靈活、松散耦合的 web 應用程序的組件。MVC 模式導致了應用程序的不同方面(輸入邏輯、業務邏輯和 UI 邏輯)的分離,同時提供了在這些元素之間的松散耦合。

  • 模型封裝了應用程序數據,並且通常它們由 POJO 組成。

  • 視圖主要用於呈現模型數據,並且通常它生成客戶端的瀏覽器可以解釋的 HTML 輸出。

  • 控制器主要用於處理用戶請求,並且構建合適的模型並將其傳遞到視圖呈現。

DispatcherServlet

Spring Web 模型-視圖-控制(MVC)框架是圍繞 DispatcherServlet

設計的,DispatcherServlet 用來處理所有的 HTTP 請求和響應。Spring Web MVC DispatcherServlet 的請求處理的工作流程如下圖所示:

技術分享圖片

下面是對應於 DispatcherServlet 傳入 HTTP 請求的事件序列:

  • 收到一個 HTTP 請求後,DispatcherServlet 根據 HandlerMapping 來選擇並且調用適當的控制器

  • 控制器接受請求,並基於使用的 GET 或 POST 方法來調用適當的 service 方法。Service 方法將設置基於定義的業務邏輯的模型數據,並返回視圖名稱到 DispatcherServlet

    中。

  • DispatcherServlet 會從 ViewResolver 獲取幫助,為請求檢取定義視圖。

  • 一旦確定視圖,DispatcherServlet 將把模型數據傳遞給視圖,最後呈現在瀏覽器中。

上面所提到的所有組件,即 HandlerMapping、Controller 和 ViewResolver 是 WebApplicationContext 的一部分,而 WebApplicationContext 是帶有一些對 web 應用程序必要的額外特性的 ApplicationContext 的擴展。

maven依賴:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>cn.spring</groupId>
  <artifactId>spring-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
   <dependencies>
      <!-- spring核心包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.5.4</version>
        </dependency>
        <dependency>
            <groupId>aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.5.4</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.11</version>
        </dependency>
        <!--mybatis核心包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.21</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
            <type>jar</type>
        </dependency>
        <!--打印日誌 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.3.13.RELEASE</version>

        </dependency>

        <!-- https://
mvnrepository.com/artifact/javax.servlet.jsp/jsp-api --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> </dependency> <!-- javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!-- spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.13.RELEASE</version> </dependency> <!-- spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.13.RELEASE</version> </dependency> <!-- 阿裏巴巴fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.41</version> </dependency> <!--dbcp --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.1.1</version> </dependency> </dependencies> </project>

簡單示例:

(1)編寫HelloController.java

package com.tutorialspoint;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.ui.ModelMap;
@Controller
@RequestMapping("/hello")
public class HelloController{ 
   @RequestMapping(method = RequestMethod.GET)
   public String printHello(ModelMap model) {
      model.addAttribute("message", "Hello Spring MVC Framework!");
      return "hello";
   }
}

(2)修改web.xml

<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>/</url-pattern>
   </servlet-mapping>

</web-app>

(3)編寫HelloWeb-servlet.xml(註意:該文件要放置WEB-INF目錄下,否則會找不到,當然了也可以指定文件路徑)

a.放在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>

b.放在src/main/resource目錄下,內容為如下即可

 <servlet>
    <description>spring mvc servlet</description>
    <servlet-name>springMvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:application-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springMvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

補充:之所以該文件夾叫HelloWeb-servlet.xml因為文件名默認會以web應用名為前綴,後面接著servlet。

<url-pattern>正則匹配攔截路徑,通常有這麽幾種形式?

其中/和/*的區別:
< url-pattern > / </ url-pattern > 不會匹配到*.jsp,即:*.jsp不會進入spring的 DispatcherServlet類 。
< url-pattern > /* </ url-pattern > 會匹配*.jsp,會出現返回jsp視圖時再次進入spring的DispatcherServlet 類,導致找不到對應的controller所以報404錯。

總之,關於web.xml的url映射的小知識:
< url-pattern>/</url-pattern> 會匹配到/login這樣的路徑型url,不會匹配到模式為*.jsp這樣的後綴型url
< url-pattern>/*</url-pattern> 會匹配所有url:路徑型的和後綴型的url(包括/login,*.jsp,*.js和*.html等)

url-patter講解:

1. 首先/這個是表示默認的路徑,及表示:當沒有找到可以匹配的URL就用這個URL去匹配。
2. 在springmvc中可以配置多個DispatcherServlet,比如: 配置多個DispatcherServlet有/和/*,先匹配的是/*這個
3. 當配置相同的情況下,DispathcherServlet配置成/和/*的區別
<一>/:使用/配置路徑,直接訪問到jsp,不經springDispatcherServlet
<二> /*:配置/*路徑,不能訪問到多視圖的jsp

當我在客戶端調用URL:/user/list然後返回user.jsp視圖,當配置的是/:DispathcherServlet拿到這個請求然後返回對應的controller,
然後依據Dispather Type為Forward類型轉發到user.jsp視圖,即就是請求user.jsp視圖(/user/user.jsp),此時Dispather沒有攔截/user/user.jsp,
因為此時你配置的是默認的/,就順利的交給ModleAndView去處理顯示了。
當配置的是/*:DispathcherServlet拿到這個請求然後返回對應的controller,然後通過Dispather Type通過Forward轉發到user.jsp視圖,
即就是請求user.jsp視圖(/user/user.jsp),此時Dispather已經攔截/user/user.jsp,Dispatcher會把他當作Controller去匹配,沒有匹配到就會報404錯誤。

實際開發建議盡量使用/,而不是/*。或者使用*.do也可以。

(4)在WEB-INF文件夾下新建jsp文件夾,並在jsp文件夾新建hello.jsp文件

hello.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<html>
<head>
<title>Hello World</title>
</head>
<body>
   <h2>${message}</h2>
</body>
</html>

(5)啟動服務器

輸入對應的視圖路徑,顯示如下結果:

技術分享圖片

Spring(十六之MVC框架