2.SpringMVC介紹 2.1.SpringMVC是什麼 SpringMVC是Spring組織下的一個表現層框架。和Struts2一樣。它是Spring框架組織下的一部分。我們可以從Spring的整體結構中看得出來: 2.2.SpringMVC的作用 1.接收Web請求中的參數 2.把處理好的數... ...
2.SpringMVC介紹 2.1.SpringMVC是什麼 SpringMVC是Spring組織下的一個表現層框架。和Struts2一樣。它是Spring框架組織下的一部分。我們可以從Spring的整體結構中看得出來: 2.2.SpringMVC的作用 1.接收Web請求中的參數 2.把處理好的數據返回給頁面 2.3.為什麼要學習SpringMVC 技術是要更新換代的,可以說Springmvc是對Struts2的技術更新,Struts2太老了,許多設計已經過時,效率不符合現在業務(互聯網)的需要,而且SpringMVC與Spring是一家的它們之間的銜接是無縫的,所以使用SpringMVC更方便和Spring進行整合。 更重要的一點是Struts2存在安全漏洞,之前的某些版本曾經造成過一些企業的損失,這也加速了Struts2的迅速老去。 那為什麼之前還要學習Struts2呢?是因為今後工作中不一定都是從事新的系統開發,你有可能去維護一個已經上線的老系統,比如許多傳統行業裡面應用的系統Struts2的使用率仍然不小,因此從學習的角度Struts2也要學習掌握。 2.4.瞭解SpringMVC的處理流程 要想引入SpringMVC做表現層開發,最基本的需要完成兩件事: 1. 配置好前端控制器DispatcherServlet。 2. 開發後端控制器併在SpringMVC的配置文件中加入企業級的配置。 3.SpringMVC環境搭建及入門程式 3.1.軟體環境 Jdk:jdk1.7.0_72 Eclipse:mars Tomcat:apache-tomcat-7.0.53 Springmvc:4.1.3 說明: 作為本課練習對jdk,eclipse版本的要求不嚴格。 但在實際項目中團隊的開發版本是有嚴格要求的,最新版本不代表是最好的,實際項目都選用最穩定的版本。 3.2.環境搭建 3.2.1.第一步:創建一個java web工程(UTF-8)並導入jar包 1.創建一個java web工程 2.導入jar包 在web工程中拷貝到lib文件夾下的jar包可以自動被導入工程 spring原生jar包: Spring常用依賴jar包: 3.2.2.第二步:配置前端控制器 【web.xml】是整個web請求的入口配置文件 <說明> ·前端控制器: org.springframework.web.servlet.DispatcherServlet,它是SpringMVC接收web請求的第一入口,也是唯一入口。這是一個servlet對象,因此需要在web.xml中進行配置。 ·<load-on-startup>:此項配置是控制當前servlet是否隨tomcat啟動而被載入 配置的值必須是整數 值 >= 0:表示當前servlet隨著tomcat啟動而被載入,值的大小表示載入的順序,越小越優先 值 < 0:表示當前servlet不會隨著tomcat啟動而被載入,只有當它被使用的時候才載入。 DispatcherServlet啟動後會立刻去找SpringMVC的配置文件,然後根據配置文件中的內容進行載入和掃描 ·<init-param>: 用這個標簽載入SpringMVC配置文件,意義就是在DispatcherServlet的初始化過程中載入配置文件, <param-name>為【contextConfigLocation】 <param-value>為【classpath:SpringMVC配置文件的類目錄下的相對路徑】 ·SpringMVC預設配置文件: 如果沒有顯示的配置SpringMVC的核心配置文件,SpringMVC會去[/WEB-INF/]下找預設的核心配置文件。預設核心配置文件的命名:servlet-name的值 + -servlet.xml。在實際工作中要知道:當發現web.xml沒有配置核心配置文件時要知道去[/WEB-INF/]下找它的預設配置文件。 因為各種框架的預設配置文件的位置可能不同,所以企業很少採用預設的配置文件路徑,因此我們需要統一規劃配置文件的存放位置,通過手動配置完成配置文件的載入。 ·常用URL樣式: [/*]: SpringMvc禁止使用,不支持。 [*.action]: 以.action為結尾的url地址請求可以進入DispatcherServlet, 放行所有資源文件尾碼的url。 [/]: 所有url地址請求均可進入DispatcherServlet, 但只放行以.jsp為結尾的url,其他資源文件尾碼的url都不放行(這個明天的RESTful的時候會具體用到, 今天先不講) 資源文件請求url: <link href="<%=basePath%>css/bootstrap.min.css" rel="stylesheet"> <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>springmvc</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 配置springmvc前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置SpringMVC的配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringMvc.xml</param-value> </init-param> <!-- 配置DispacherServlet隨tomcat啟動而被載入 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 配置什麼樣的url路徑可以進入DispatcherServlet --> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app> 3.2.3.第三步:創建springmvc核心配置文件 新建一個source folder: config 在config下創建一個xml文件: SpringMvc.xml,文件頭可以從其他地方直接拷貝過來。 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> </beans> 3.2.4.第四步:啟動tomcat測試環境 到此為止SpringMvc基本框架搭建完成,啟動tomcat,日誌中不報錯,就說明環境搭建成功。 下麵就是入門程式的開發。 3.3.案例需求 3.3.1.需求 使用SpringMVC實現商品列表的展示。 3.3.2.需求分析 1.要展示全部商品列表,所以不需要參數,請求url: http://localhost:8080/<具體web應用的名字>/list.action 2.主要關註SpringMvc的入門程式,所以暫不考慮連接資料庫等多餘功能,在業務處理中只做假的模擬數據返回給頁面。 3.4.入門程式 3.4.1.第一步:創建jsp頁面 創建jsp頁面的目錄: 前端頁面不是本課內容,參考: 參考資料\參考案例\jsp\itemList.jsp直接拷貝到工程jsp目錄中。 問題:放在WebContent目錄下和放到WEB-INFO目錄下的區別? WEB-INFO是受tomcat保護目錄,它裡面的文件只能由servlet去訪問,不能通過url地址欄去請求訪問。 WebContent下的文件可以直接通過url地址欄去訪問,一般的歡迎頁和靜態資源文件都放在這裡。 3.4.2.第二步:創建和配置後端控制器 創建包: cn.baidu.controller用於存放後端控制器,cn.baidu.pojo用於存放保存返回數據的bean 創建後端控制器類: <說明> ·@Controller:表明用這個註解修飾的類需要SpringMVC掃描成SpringMVC的組件。 package cn.baidu.controller; import org.springframework.stereotype.Controller; // 定義一個java類,@Controller註解標註在類定義的上方表明這個類需要SpringMVC掃描。 @Controller public class ItemsController { } 在SpringMvc.xml中配置後端控制器類的掃描 <說明> <context:component-scan base-package="要掃描的包路徑" /> 掃描指定包及子包下的@Controller、@Service、@Repository等註解修飾的java類。 其中在SpringMVC配置文件中只掃描@Controller修飾的類所在的包,並註冊為SpringMVC的組件。 其它註解修飾的類在Spring配置文件中掃描,並註冊為Spring的組件。 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置SpringMVC下Controller類的掃描 --> <context:component-scan base-package="cn.baidu.controller" /> </beans> 註意: 如果想掃描多個包,可以配置多個<context:component-scan base-package="指定的包名" /> 3.4.3.第三步:編寫方法響應url請求 註解類型的Controller類中使用@RequestMapping註解修飾的方法響應url請求。一個url對應一個方法。不可能多個url同時對應一個方法,也不可能多個方法同時響應一個url請求。 <說明> ·@RequestMapping(“具體URL”): 指明這個方法響應的具體url是什麼。這裡面配置的url是工程名後的具體url,以【/】開頭,如果不寫【/】也可以,推薦寫。 @RequestMapping(“具體URL”)和它修飾的方法就形成一對key/value,key就是URL,value就是由註解修飾的方法包裝在handler對象中(handler是SpringMVC內置的專門用來封裝url請求響應方法的對象),最終再把這些key/value放到一個map對象中保存。 ·Model: 模型對象,是SpringMVC預設支持的一種形參類型, 作用:負責將返回給頁面的數據賦值給request對象(這個賦值的過程是SpringMVC底層做的,將你賦給Model對象的屬性名和值賦給request對象,這個詳細過程不需要我們掌握它的詳細邏輯,理解一下即可。) 這樣JSP就可以用EL表達式從request對象中取得這個屬性名的數據了。 ·記住:對於jsp永遠都是從request對象中通過屬性名取值。 package cn.baidu.controller; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import cn.baidu.pojo.Items; // 定義一個java類,@Controller註解標註在類定義的上方表明這個類需要SpringMVC掃描。 @Controller public class ItemsController { // 標註url到請求方法的key/value對應關係 @RequestMapping("/list") public String list(Model model) throws Exception { //商品列表(臨時數據) List<Items> itemsList = new ArrayList<Items>(); Items items1 = new Items(); items1.setName("聯想筆記本"); items1.setPrice(6000f); items1.setDetail("ThinkPad T430 聯想筆記本電腦!"); Items items2 = new Items(); items2.setName("蘋果手機"); items2.setPrice(5000f); items2.setDetail("iphone6蘋果手機!"); itemsList.add(items1); itemsList.add(items2); // 1. 設置返回給頁面的數據 // 第一個參數是屬性名稱, 第二個參數是屬性值 //model在SpringMVC底層是將它裡面的屬性名和屬性值賦值給了request對象,而jsp頁面通過request域進行取值 model.addAttribute("itemList", itemsList); //簡化完的剩餘的字元串叫做視圖的邏輯視圖名 //視圖的物理路徑 = 首碼 + 邏輯視圖名 + 尾碼. return "itemList"; model.addAttribute("itemsList", itemsList); // 2. 指定返回頁面的地址 return "/WEB-INF/jsp/itemList.jsp"; } } 返回的頁面是否存在、是否正確都需要先判斷一下,在SpringMVC中使用一個視圖解析器的組件來做這些處理。 配置視圖解析器:在SpringMVC.xml中配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置指定包下的組件掃描 --> <context:component-scan base-package="cn.baidu.controller" /> <!-- 配置視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> </bean> </beans> 3.4.4.第四步:啟動tomcat測試 訪問地址: http://localhost:8080/springmvc/list.action 3.4.5.第五步:優化方法的返迴路徑 上面直接返回jsp的路徑倒是很直接,但是每個方法都返回一長串路徑看著有點亂,而且每個方法返回的路徑中【/WEB-INF/jsp/】和【.jsp】都是重覆的,未免顯得有些冗餘。 能否將這些重覆的部分提取出來放到SpringMVC的配置文件中呢?答案是肯定的——修改視圖解析器的配置: 【SpringMVC.xml】中配置視圖解析器的首碼和尾碼專門用來拼接視圖文件的路徑: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置指定包下的組件掃描 --> <context:component-scan base-package="cn.baidu.controller" /> <!-- 配置視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 首碼 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 尾碼 --> <property name="suffix" value=".jsp" /> </bean> </beans> 說明: 1.作用: 用視圖解析器中配置的首碼和尾碼簡化Controller類中的編碼 2.代碼的簡化: ······ // 2. 指定返回頁面的地址 return "itemList"; ······ 3.邏輯視圖名與視圖文件物理路徑 簡化後Controller方法中返回的字元串叫做邏輯視圖名。 視圖文件物理路徑=首碼 + 邏輯視圖名 + 尾碼。 SpringMVC能保證每次返回的字元串都會自動走視圖解析器,然後按照上面的方式拼接,再進行後續處理。 3.5.本節總結 本單元內容主要是搭建了一個SpringMVC開發環境並學習了它的入門程式。 這個開發環境只有SpringMVC,所以不是我們正式的環境,瞭解即可,不重要。 入門程式中學習到的兩個註解@Controller和@RequestMapping用法以及返回數據和返回頁面的處理方式要掌握。 <!-- 配置後端控制器的掃描 --> <!-- 這個標簽可以掃描的註解 : @Controller , @Service, @Repository,這是前三個的父註解@Compontent --> <context:component-scan base-package="cn.baidu.controller"></context:component-scan> <!-- 顯示配置處理器映射器和處理器適配器 --> <!-- 預設形式的處理器映射器和處理器適配器 : 預設的組件是不推薦使用的,因為它們是舊版 DefaultAnnctationHandlerMapping和AnnotationMethodHandlerAdapter --> <!-- 配置當前版本下最新的註解形式的處理器映射器和處理器適配器 : 雖然是最新的,但是一旦版本變更可能會引起新的修改--> <!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> --> <!-- 企業中系統一勞永逸的方式 : 註解驅動方式 --> <!-- 作用 : 會載入當前版本下最新的註解形式的處理器映射器和處理器適配器,能提高執行效率 --> <mvc:annotation-driven/> <!-- 配置視圖解析器 --> <!-- 這個視圖解析器就是用來解析jsp頁面的,也是springmvc預設的視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置首碼和尾碼為了簡化開發 --> <property name="prefix" value="/WEB-INF/jsp/"></property> <!-- 配置尾碼 --> <property name="suffix" value=".jsp"></property> </bean> 4.SpringMVC框架 4.1.框架結構(重點) 1.學習框架結構的目的: 開發不用, 但面試時會問到 2.框架結構詳細內容:(面試題) 說明:前端控制器是接收web請求的入口,地位最重要。如果還要做其他具體的工作會使它的負擔過於繁重,因此SpringMVC找來了四個幫手,叫做四個組件,來幫助前端控制器承擔一些具體的工作,這樣前端控制器就只發號司令做為集中控制調度中心,具體的工作交給四個組件來完成。 具體工作分為兩部分: 1.處理請求:兩個組件,一個來找Handler,一個來執行Handler 1)處理器映射器負責找到URL對應的Handler對象 2)處理器適配器負責執行找到的Handler對象。 2.返回結果:兩個組件,一個來找頁面,一個來執行頁面渲染 1)視圖解析器負責找到要返回的頁面 2)視圖對象負責渲染頁面,渲染頁面需要的數據由前端控制器傳給它。 ●啥是freemaker? 就是模版, 通過模版和數據生成輸出的文本(HTML網頁, 電子郵件等). 比如網易首頁點擊進入的一個html頁面, 這些靜態的html都是由freemarker生成的, 而struts2只支持jsp. 4.2.框架流程 1.用戶發送請求至前端控制器DispatcherServlet 2.DispatcherServlet收到請求調用HandlerMapping處理器映射器。 3.處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一併返回給DispatcherServlet 4.DispatcherServlet通過HandlerAdapter處理器適配器調用處理器 5.執行處理器(handler也叫後端控制器-->Service-->DAO) 6.Handler執行完成返回ModelAndView 7.HandlerAdapter將handler執行結果ModelAndView返回給DispatcherServlet 8.DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器 9.ViewReslover根據handler中設置的頁面信息解析成一個View視圖對象並返回它. 10.DispatcherServlet調用View對象的介面方法對實際的視圖文件(如: jsp文件)進行渲染(即將模型數據填充至視圖文件中) 11.DispatcherServlet響應用戶 口述 : 先掃描@Controller修飾的類 打開這個類找出裡面所有由@Requestmapping修飾的方法 通過反射得到這個方法的method對象 把method對象封裝到一個handler對象中(handlder是SpringMVC內置的對象用來統一調用方法的) 最終把RequestMapping中配置的url作為key,把handler對象作為value放到一個map對象中 這個map對象由處理器映射器來維護 4.3.需要認識的SpringMVC組件 SpringMVC的整個控制層採用組件式的結構。 SpringMVC的組件有: 前端控制器DispatcherServlet、 處理器Handler(相對於前端控制器的後端控制器)、 處理器映射器HandlerMapping、 處理器適配器HandlerAdapter、 視圖對象View、 視圖解析器ViewResolver。 其中HandlerMapping、HandlerAdapter、ViewResolver是springmvc的三大核心組件,Handler涉及具體業務需要程式員實現,View由ViewResolver生成,負責渲染頁面。 三大組件乾的事情其實都可以集中交給DispatcherServlet來乾,但都交給它會使它過於臃腫,處理效率會大大降低,因此分而治之才是上策。 4.3.1.DispatcherServlet:前端控制器 DispatcherServlet負責接收用戶請求,是整個流程的控制中心,但它幾乎不做任何具體的工作,只進行任務調度。具體的工作由具體的組件來完成。這就是組件式結構的優勢,專項事情又專門的組件來做,這樣能提高專項的處理能力同時集中調度的存在降低了組件之間的耦合性。 4.3.2.Handler:處理器 在DispatcherServlet的控制下Handler對具體的用戶請求進行處理。 由於Handler涉及到具體的用戶業務請求,所以一般情況需要程式員根據業務需求開發Handler。 4.3.3.HandlerMapping: 處理器映射器 HandlerMapping負責為每個請求找到一個合適的處理器handler,其實簡單來說就是維持了一個url到handler的映射Map。springmvc提供了不同的映射器,實現不同的映射方式,例如:配置文件方式,實現介面方式,註解方式等。 比如註解方式的映射器會根據核心配置文件中配置的<context:component-scan base-package="包路徑" />指定的包路徑(包括子目錄)進行掃描,找@Controller標註的Java類,該類中所有使用@RequestMapping修飾的方法都是一個handler對象,並根據@RequestMapping的值作為key,對應的方法的handler對象作為value,形成一個url到方法的k/v鍵值對映射。而且這種掃描只要在tomcat啟動時做一次,不會影響系統的性能。 4.3.4.HandlerAdapter: 處理器適配器 1.什麼是適配器: 2.適配器的作用:統一調用介面,好擴展。 3.Springmvc中的處理器適配器: 處理器適配器HandlerAdapter負責執行具體的處理器。 SpringMVC有多個適配器,當HandlerMapping找到了url對應的handler對象後,前端控制器會挑選一個能夠執行這個handler的處理器適配器,然後給這個適配器發送指令,同時把這個handler對象傳給這個適配器,讓它執行handler,最終將handler的返回值和邏輯視圖名字元串返回給前端控制器。 4.3.5.ViewResolver: 視圖解析器 視圖解析器(ViewResolver)負責解析出視圖文件的物理路徑,並根據這個路徑生成視圖View對象。 ViewResolver首先把邏輯視圖名解析成實際的頁面位置,再生成視圖View對象並返回給前端控制器。 4.3.6.View:視圖對象類型 1.View視圖對象 View對象負責渲染視圖文件,將數據結果通過視圖文件展示給用戶。前端控制器調用View對象的介面方法render(),參數就是後臺返回的數據,在render方法拿數據渲染視圖文件生成返回給客戶端的結果。 springmvc框架提供了很多的View類型,包括:jstlView、freemarkerView、pdfView等。 2.視圖文件 視圖文件可以是jsp、pdf、freemaker等,最常用的就是jsp。一般情況下需要通過頁面jsp標簽或頁面模版將處理器返回的model數據通過頁面展示給用戶,需要由程式員根據業務需求開發具體的頁面。 4.3.7.組件總結 SpringMVC的三大組件(理解記憶):處理器映射器、處理器適配器、視圖解析器 需要程式員編寫代碼的有:處理器(包括處理器、具體業務的service和dao)、視圖文件(jsp) 4.4.SpringMvc三大組件的配置 Springmvc三大組件配置在核心配置文件中,springmvc支持組件免配置、顯示配置和企業的配置方法 4.4.1.組件的免配置 1.何為免配置: 即什麼都不配。此時SpringMVC仍然可以正常運行,全憑它自己的DispatcherServlet.properties,會從中找到合適的組件去執行。這個屬性文件的位置: 2.DispatcherServlet.properties的作用: 如果沒有顯示配置三大組件(其中一個或者全部),依靠這個屬性文件中的預設配置組件,springmvc也能正確的執行。 3.上面的入門程式中自動選擇的三大組件分別是: a)處理器映射器 b)處理器適配器 c)視圖解析器 預設的視圖解析器只有一個。 4.壞處: 每次請求都要去這裡去找合適的組件,所以執行效率很低,因此什麼都不配置是不可取的。需要我們顯示配置來提高執行效率。 4.4.2.SpringMvc顯式配置處理器映射器和處理器適配器 1.顯式配置預設選擇的處理器映射器和處理器適配器(舊版) 2.顯式配置官方推薦的處理器映射器和處理器適配器(新版) 3.企業中的配置方法:註解驅動 作用:幫助我們顯式配置當前Spring版本的最新的註解形式的處理器映射器和處理器適配器 好處:簡化配置,一勞永逸 4.面試題: springmvc是否要配置註解驅動和註解掃描? 有什麼區別? 答: 都需要配置,兩個東西的作用完全不一樣,不要混淆視聽。 註解驅動:作用就是替我們顯式的配置當前spring版本下最新版本的註解形式的處理器映射器和處理器 適配器 註解掃描:掃描指定包及子包下的@Controller、@Service、@Repository等註解修飾的java類,其 中@Controller修飾的類註冊為SpringMVC的組件,其它註解修飾的類註冊為Spring的 組件。 4.4.3.SpringMvc顯式配置視圖解析器 前面已經學過,此處只給出配置的例子。 4.4.4.顯示配置的意義 處理器映射器、適配器:提高執行效率 視圖解析器(有首碼和尾碼):簡化編碼 4.5.本節重點 掌握: SpringMVC的框架流程,能說出來從請求到返回頁面的處理流程; SpringMVC三大組件的最終形態的顯示配置方法。 理解: 三大核心組件的功能。 瞭解: Springmvc預設組件配置; 單獨配置新版的處理器映射器和處理器適配器。 下麵是完整的springmvc核心配置文件的配置:SpringMVC.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置指定包下的組件掃描 --> <!-- 作用:SpringMVC可以自動去掃描指定包以及子包下的java文件,如果掃描到有@Controller(控制層的類) @Service(業務層的類) @Repository(資料庫訪問層的類)這些註解修飾的類,則把這些類註冊為 SpringMVC的組件 --> <context:component-scan base-package="cn.baidu.controller" /> <!-- 1. SpringMVC預設的三大組件選擇(處理器映射器、處理器適配器、視圖解析器) 如果沒有顯示的配置三大組件,SpringMVC也能正常執行,是因為會預設去找SpringMVC的預設 屬性文件DispatcherServlet.properties,從中找到合適的三大組件去執行。但這種方式在麽次 請求的時候都會去找一遍,所以效率很低,因此採用預設的三大組件選擇是不可取的。 我們應該顯示的配置它們,這樣可以提高系統的訪問效率。 --> <!-- 2. 顯示的配置處理器映射器和處理器適配器 --> <!-- 預設的註解形式的處理器映射器:老版本,不推薦使用 --> <!-- <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> --> <!-- 預設的註解形式的處理器適配器:老版本,不推薦使用 --> <!-- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> --> <!-- 當前最新版本的註解形式的處理器映射器 --> <!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" /> --> <!-- 當前最新版本的註解形式的處理器適配器 --> <!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" /> --> <!-- 3. 企業中配置註解形式的處理器映射器和處理器適配器的方法:註解驅動 --> <!-- 作用:顯示的配置了當前Spring版本下最新的註解形式的處理器映射器和處理器適配器。由於它 沒有和任何class關聯,所以即使Spring版本升級,該項配置也不會發生任何改動,企業中 喜歡採用這種一勞永逸的方法。 --> <mvc:annotation-driven /> <!-- 配置視圖解析器 --> <!-- 作用:利用顯示配置視圖解析器中的首碼和尾碼可以簡化Controller方法中的視圖信息的設置,只需 在setViewName方法中設置邏輯視圖名稱(視圖文件的名稱,比如jsp文件)即可。每次視圖解 析器都會自動的進行視圖文件物理路徑的拼接:首碼 + 邏輯視圖名稱 + 尾碼。從而方便了我們的 編碼工作。 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 首碼 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 尾碼 --> <property name="suffix" value=".jsp" /> </bean> </beans> 5.SSM整合 5.1.SSM整合包含的框架 5.2.SSM整合思路 5.2.1.整合思路的重要性 整合的步驟是固定的, 過程是可以複製的, 人家告訴我們怎麼整合就怎麼來做就可以了. 具體來說, 第一是你手頭有現成的資料照著做即可; 第二如果你沒有資料, 怎麼辦? 這時候如果能記住思路, 我們就可以上網去找資料. 但如果思路記不住就連資料怎麼找都不知道了, 所以說思路是很重要的, 要記住. 5.2.2.具體的整合思路(重點) 首先,先劃分大層次,整合後分為三層:表現層 業務層 數據訪問層,再加上web.xml這是整體的骨架; 其次,再逐層規劃每一層具體要乾什麼。 ssm整合的思路如下: Spring與MyBatis的整合在MyBatis第二天的時候已經學習過了,這裡仍然沿用。SpringMVC與Spring又是一家的,所以它們之間是不需要整合配置的,即所謂的無縫整合,直接就可以用,只不過需要在web.xml中配置它們兩個。具體規劃如下: SSM整合分三層:DAO層、Service層、Controller層 代碼目錄: ·DAO層: pojo:pojo類 dao:映射文件、介面文件——Mybatis逆向工程自動生成,DAO通過SM整合jar包來掃描 ·Service層: service:service介面和實現類——利用@Service註解修飾,讓spring來掃描 ·Controller層: controller:Controller類及方法——利用@Controller註解修飾,讓SpringMVC來掃描 配置目錄: ·config: MyBatisConfig.xml——MyBatis配置 ApplicationContext-dao.xml——數據源、連接池、會話工廠、mapper包掃描 ApplicationContext-service.xml——註解掃描(service層的組件掃描)、事務管理 (以上兩個配置文件可以配置在一個文件中,這裡為了體現分層的思路所以分開配置。) SpringMVC.xml——註解掃描(Controller層的組件掃描)、註解驅動、視圖解析器 web.xml Spring監聽(管理service層和dao層)、SpringMVC前端控制器(管理Controller層) JSP:在【/WEB-INF/】創建jsp目錄,存放jsp頁面。 面試題:事務配置在哪一層?為什麼? 事務配置在service層,因為service層控制的是業務,在一個service中有可能調用多個DAO中的方法進行一系列的操作,這些操作要麼都成功,要麼都失敗。比如匯款,匯出操作成功了,但是存入給另一個人時發現卡被註銷了,這個時候要整個業務回滾,否則錢就會丟失,所以必須在service層做事務控制。 註意: 不要糾結Controller層的類域Service層的類能否放到一個目錄下。這個問題沒有意義,因為分層的意思就是強制將它們分開,Controller層的目錄就放Controller的類,Service層的目錄就放Service的類,DAO層的目錄就放Dao的類。 配置文件是否合併的問題,這個問題也不要糾結,看個人喜好,如果想讓配置文件單一化,就可以把兩個ApplicationContext文件合併,但SpringMVC.xml與ApplicationContext不要合併,因為前者是表現層由Spring的子集框架SpringMVC專門負責,後者是業務層以及DAO層由Spring本身自己負責。 5.3.軟體環境 Jdk: jdk1.7.0_72 Eclipse: mars Tomcat: apache-tomcat-7.0.53 Springmvc: 4.1.3 MyBatis: mybatis-3.2.7 MySql: 5.1.28 SM整合包: 1.2.2 5.4.資料庫環境 使用【資料\參考案例\sql】下的創建庫建表腳本【springmvc.sql】創建我們使用的資料庫環境。 5.5.SSM整合步驟 5.5.1.第一步: 新建一個web工程 5.5.2.第三步: 導入jar包 將【資料\jar\ssm整合後jar全集】下的jar包拷貝到WebContent/WEB-INF/lib下, 會自動關聯到工程中 5.5.3.第二步: 創建目錄結構 根據思路創建工程目錄: 1.代碼目錄: cn.baidu包下創建四個子包 controller: 存放cnotroller層的代碼 service : 存放service層的代碼 dao: 存放dao層的代碼 pojo: 存放pojo的代碼 2.配置文件目錄: 選擇工程右鍵創建source folder: config, 用於存放全部配置文件. 3.視圖目錄: 在WebContent/WEB-INF下創建jsp目錄,用於存放jsp文件. 5.5.4.第四步: 使用mybatis逆向工程生成代碼 1.將【資料\MyBatis逆向工程】下的【MyBatisGeneration】工程導入eclipse。 2.修改配置文件符合當前的開發環境和目錄結構。 a)資料庫名 b)Pojo包名 c)Mybatis映射文件的包名 d)Mybatis映射介面的包名(與c相等) e)需要生成代碼的資料庫表 3.註意: a)執行前要把原先舊的代碼全部刪除。 b)執行完生成程式後第一次刷新的時候表現出來的包名不對,再刷新一次就好了。這是eclipse的一個bug。 4.將生成的代碼拷貝到我們的工程中去。 5.5.5.第五步: 創建DAO層配置文件 1.在【資料\參考案例\config】下是mybatis課程中sm整合的時候需要的配置文件,整體導入。 2.整理mybatis的配置文件: a)MyBatisConfig.xml:清空<configuration>標簽內全部的內容,保留一個空的配置文件是為了今後對mybatis的擴展。 b)ApplicationContext.xml:保留其中的屬性文件、數據源(連接池)、會話工廠、動態代理包掃描的配置,其他的都刪除。根據上面的思路它應該屬於dao層的spring配置文件,改名為ApplicationContext-dao.xml c)其他配置文件保持不變。 3.修改後的配置文件: 【MyBatisConfig.xml】 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 類型別名的配置 --> <!-- <typeAliases> <typeAlias type="cn.baidu.pojo.UserModel" alias="UserModel"/> <package name="cn.baidu.pojo"/> </typeAliases> --> </configuration> 【ApplicationContext-dao.xml】 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 1 屬性文件的配置 --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 2 數據源的配置 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxActive" value="10" /> <property name="maxIdle" value="5" /> </bean> <!-- 3 MyBatis的會話工廠的配置 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:MyBatisConfig.xml" /> <property name="dataSource" ref="dataSource" /> </bean> <!-- 4 動態代理包掃描的配置 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.baidu.dao" /> </bean> </beans> 5.5.6.第六步: 創建Service層配置文件 創建【ApplicationContext-service.xml】,@Service註解組件的掃描和事務管理 【ApplicationContext-service.xml】 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- service層的組件掃描 --> <context:component-scan base-package="cn.baidu.service" /> <!-- 事物管理配置 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 數據源 --> <property name="dataSource" ref="dataSource"/> </bean> <!-- 通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 傳播行為 --> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="find*" propagation="SUPPORTS" read-only="true" /> <tx:method name="get*" propagation="SUPPORTS" read-only="true" /> </tx:attributes> </tx:advice> <!-- 切麵 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.baidu.service.*.*(..))" /> </aop:config> </beans> 5.5.7.第七步: 創建SpringMvc.xml 創建【SpringMvc.xml】,配置@Controller註解組件掃描,註解驅動,視圖解析器 配置文件: 【SpringMvc.xml】 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- controller層的組件掃描 --> <context:component-scan base-package="cn.baidu.controller" /> <!-- 配置註解驅動 --> <mvc:annotation-driven /> <!-- 配置視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 首碼 --> <property name="prefix" value="WEB-INF/jsp/" /> <!-- 尾碼 --> <property name="suffix" value=".jsp" /> </bean> </beans> 5.5.8.第八步: 配置web.xml 配置spring的容器監聽、springmvc前端控制器以及它可接收的url地址。 配置文件: 【web.xml】 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>ssm</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 配置spring的容器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:ApplicationContext-*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 配置springmvc的前端控制器--> <servlet> <servlet-name>springMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定springmvc核心配置文件的位置 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringMVC.xml</param-value> </init-param> <!-- 標記是否在tomcat啟動時就載入當前的servlet --> <load-on-startup>1</load-on-startup> </servlet> <!-- 配置springmvc前端控制器能夠接收的url結尾格式 --> <servlet-mapping> <servlet-name>springMvc</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app> 5.5.9.小結 本節的重點是要掌握整合的思路,有了思路就可以尋著線索進行整合了,不用死記具體的過程。 5.6.整合後的案常式序 5.6.1.需求 使用SSM從資料庫查詢數據, 實現真正的商品列表的展示. 5.6.2.需求分析 1.沿用SpringMvc入門程式. 2.在此基礎上完成service層的代碼, 定義service介面和實現類, 並用@autowired自動註入DAO介面對象. 3.完善controller層代碼, 用@autowired自動註入service介面對象. 5.6.3.第一步: 創建service層的介面和實現類 1.定義ItemsService.java介面 2.定義ItemsServiceImpl.java實現類,實現這個介面 代碼: 【ItemsService.java】 package cn.baidu.service; import java.util.List; import cn.baidu.pojo.Items; public interface ItemsService { public List<Items> findItemsList() throws Exception; } 【ItemsServiceImpl.java】 package cn.baidu.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import cn.baidu.dao.ItemsMapper; import cn.baidu.pojo.Items; @Service public class ItemsServiceImpl implements ItemsService { @Autowired ItemsMapper itemsMapper; @Override public List<Items> findItemsList() throws Exception { // 通過自動生成的介面方法查詢商品列表 List<Items> list = itemsMapper.selectByExample(null); return list; } } 註意:selectByExample(null)只檢索除了大對象數據類型之外的欄位,但items表中有一個detail欄位的類型是text,為了把它也檢索出來可以使用selectByExampleWith