MVC開始是存在於桌面程序中的,M是指業務模型,V是指用戶界面,C則是控制器
使用MVC的目的是將M和V的實現代碼分離,從而使同一個程序可以使用不同的表現形式。比如一批統計數據可以分別用柱狀圖、餅圖來表示。C存在的目的則是確保M和V的同步,一旦M改變,V應該同步更新。
Model(模型)
表示應用程序核心(比如數據庫記錄列表)。
是應用程序中用於處理應用程序數據邏輯的部分。
通常模型對象負責在數據庫中存取數據。
View(視圖)
顯示數據(數據庫記錄)。
是應用程序中處理數據顯示的部分。
通常視圖是依據模型數據創建的。
Controller(控制器)
處理輸入(寫入數據庫記錄)。
是應用程序中處理用戶交互的部分。
通常控制器負責從視圖讀取數據,控制用戶輸入,並向模型發送數據
視圖
模型
控制器
MVC 從邏輯上把應用分為模型組件,視圖組件和控制器組件。其中控制器組件又可以細分為:前端控制器組件和后端控制器組件。
MVC 的基本工作流程:
首先是客戶端(通常是瀏覽器)發出一個請求。第一個接受這個請求的組件一般是一個前端控制器。它將不同的請求交給不同的后端控制器來處理,而在后端控制器里面又可以調用相應的模型對象來處理具體的業務邏輯,最后再返回一個特定的視圖響應給客戶端。
第一個接受這個請求的前端控制器叫 DispatcherServlet
后端控制器叫 Controller
負責處理請求 URL 和后端控制器映射的叫 HandMapping(它有多種類型,比較靈活,也是在一個 xml 文件上進行配置)
負責業務邏輯處理的模型對象一般也是我們平常寫的 DAO/DTO 組件(只是它最后的返回更靈活, Controller 返回一個 ModelAndView 對象給 DispatcherServlet , ModelAndView 可以攜帶一個視圖對象,也可以攜帶一個視圖對象的邏輯名。如果攜帶的是一個視圖對象的邏輯名,那 DispatcherServlet 需要一個 ViewResolver 來查找用於渲染回應的視圖對象。最后, DispatcherServlet 將請求分派給 ModelAndView 對象指定的視圖對象。視圖對象負責渲染返回給客戶的回應。)
跑一個最簡單的例子,讓大家對構建 SpringMVC 的基本步驟有個直觀的認識
(1) 建立動態 web 工程,導入 spring 的 jar 包。
(2) 配置 DispatcherServlet
DispatcherServlet 是 SpringMVC 的核心,將下面 Servlet 的注冊信息登記在 web.xml 中
<servlet> <servlet-name> test </servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class>
<load-on-startup> 1 </load-on-startup>
</servlet> <servlet-mapping> <servlet-name> test </servlet-name> <url-pattern> *.do </url-pattern> </servlet-mapping>
(3) 編寫 Controller ,做核心配置文件,並配置 url 和 Controller 的映射
package com.wepull.test; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; public class HelloController implements Controller{ public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { request.setAttribute( "hello" , "welcome to spring!" ); return new ModelAndView( " welcome " ); } }
在 WEB-INF 下新建一 XML 文件 : test -servlet.xml. 注意,這里的 test 取決於 servlet 的名字 . 當 DispatcherServlet 載入后,它將試圖從這個文件中載入應用上下文。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- 缺省映射處理器,不需要明確聲明,但聲明后就非常清楚使用的是哪個映射處理器 -->
<bean id = "beanNameUrlMapping" class = "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> </bean> <!-- 這里的 name 屬性有兩個職責,既定義 Bean 的名字,也定義需要這個控制器處理的 URL 樣式 --> <bean name = "/hello.do" class = "com.wepull.test.HelloController"> </bean> </beans>
上面可能有人奇怪,為什么不用 id 屬性,而設置 name 屬性。這里是因為 URL 中含有 XML id 屬性非法字符——特別是斜杠( / ) ;
(4) 配置一個視圖解析器將控制器與 JSP 結合起來。
將解析器的配置片段加到上面的 test-servlet.xml 中
<bean id = "viewResolver" class = "org.springframework.web.servlet.view.InternalResourceViewResolver"> < property name = "prefix" value = "/WEB-INF/jsp/" /> < property name = "suffix" value = ".jsp" /> </bean>
InternalResourceViewResolver 在 ModelAndView 返回的視圖名前加上 prefix 屬性配置的前綴 , 再在最后加上 suffix 屬性配置的后綴。如 HelloController 返回的 ModelAndView 中視圖名為 welcome, 所以 InternalResourceViewResolver 將在 /WEB-INF/jsp/welcome.jsp 處查找視圖。
(5) 編寫呈現給用戶的 jsp 文件。
/WEB-INF/jsp/welcome.jsp
<%@ page contentType = "text/html; charset=UTF-8" %> <%@ page isELIgnored = "false" %> <%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %> <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" > < html xmlns = "http://www.w3.org/1999/xhtml" > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" /> < title > Hello World! </ title > </ head > < body > < h2 > ${hello} </ h2 > </ body > </ html >
完成后啟動服務器,在瀏覽器地址欄上輸入 http://locahost:8080/projectName/hello.do 就可以訪問了。
mvc中的映射關系HandlerMapping
springMVC 里有個映射處理器 (HandlerMapping) 的概念。它實際上是一個處理器映射 Bean, 用來將一個控制器指定到一個 URL 上。 Spring 提供了三種有用的 HandlerMapping 的實現:
BeanNameUrlHandlerMapping
根據控制器的名字將控制器映射到 URL
SimpleUrlHandlerMapping
用上下文配置文件中定義的屬性集合將控制器映射到 URL
CommonsPathMapHandlerMapping
使用控制器代碼中的元數據將控制器映射到 URL
mvc中的試圖解析器ViewResolver
springMVC 里還有個視圖解析器 (ViewResolver) 的概念。它決定了 ModelAndView 對象的邏輯視圖名如何解析成一個用於將結果渲染給用戶的視圖 Bean..Spring 有四種 ViewResolver 實現:
InternalResourceViewResolver
將邏輯視圖名解析成一個用模板文件 ( 如 JSP 和 Velocity 模板 ) 渲染的視圖對象
BeanNameViewResolver
將邏輯視圖名解析成一個 DispatcherServlet 應用上下文中的視圖 Bean
ResourceBundleViewResolver
將邏輯視圖名解析成一個 ResourceBundler 中的視圖對象
XmlViewResolver
從一個 XML 文件中解析視圖 Bean, 這個文件是從 DispatcherServlet 應用上下文中分離出來的。
