1. 瞭解SpringMVC
1. springmvc是spring框架的一個模塊,springmvc和spring無需通過中間整合層進行整合(比如Mybatis與Spring整合的時候需要藉助單獨的jar包)。springmvc是一個基於mvc模式的web框架。
2. SpringMVC對於從客戶端發來的請求的處理流程:
第一步:發起請求到前端控制器(DispatcherServlet)
第二步:前端控制器請求HandlerMapping查找 Handler,可以根據xml配置、註解進行查找
第三步:處理器映射器HandlerMapping向前端控制器返回Handler
第四步:前端控制器調用處理器適配器去執行Handler
第五步:處理器適配器去執行Handler
第六步:Handler執行完成給適配器返回ModelAndView
第七步:處理器適配器向前端控制器返回ModelAndView,ModelAndView是springmvc框架的一個底層對象,包括 Model和view
第八步:前端控制器請求視圖解析器去進行視圖解析,根據邏輯視圖名解析成真正的視圖(jsp、pdf等)
第九步:視圖解析器向前端控制器返回View
第十步:前端控制器進行視圖渲染,視圖渲染將模型數據(在ModelAndView對象中)填充到request域
第十一步:前端控制器向用戶響應結果
3. SpringMVC中的重要組件:
- 前端控制器DispatcherServlet(不需要程序員開發):用於接收請求,響應結果,相當於轉發器,中央處理器。有了DispatcherServlet減少了其它組件之間的耦合度。
- 處理器映射器HandlerMapping(不需要程序員開發):根據請求的url查找Handler
- 處理器適配器HandlerAdapter:按照特定規則(HandlerAdapter要求的規則)去執行Handler(或者說Controller)
- 處理器Handler(或者說Controller,需要程序員開發),注意:編寫Handler時按照HandlerAdapter的要求去做,這樣適配器纔可以去正確執行Handler
- 視圖解析器View resolver(不需要程序員開發):進行視圖解析,根據邏輯視圖名解析成真正的視圖(view)
- 視圖View(需要程序員開發jsp),View是一個接口,實現類支持不同的View類型(jsp、freemarker、pdf...)
2. SpringMVC的簡單使用
1. 準備環境:新建一個Maven項目,導入所需要的相關jar包
2. 首先配置前端解析器,修改項目的web.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>SpringWebMVC</display-name>
<!-- 配置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:conf/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!--
前端控制器的url-pattern有三種形式:
1.*.xx:即只會解析以".xx"結尾的路徑
2./ :所有的訪問地址都會被前端控制器解析,對於靜態文件的路徑訪問需要特殊配置不被前端控制器解析,
因爲依據靜態文件的路徑,前端控制器是無法找到對應的Handler的,所以會報錯,
使用此形式的url-pattern可以實現RESTful路徑風格
3./*:此種方式有錯誤,當最終轉發到一個jsp頁面時,仍會有前端控制器解析jsp頁面路徑,而依據此路徑
前端控制器是無法找到對應的Handler的,所以會報錯
-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<!-- 配置SpringMVC的RESTful路徑風格的前端控制器,兩個前端控制器可以並存不會影響 -->
<!-- 關於RESTful風格的url-pattern所帶來的無法解析靜態資源(js,css)路徑問題,將在SpringMVC
配置文件中進行特殊配置,避免只解析部分路徑,即/js/**.js只解析/js路徑而缺失了/**.js-->
<servlet>
<servlet-name>springmvc_RESTful</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc_RESTful</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2. 在上面指定的classpath:conf/springmvc.xml文件中配置SpringMVC的註解式處理器映射器和處理器適配器:
<?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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
<!-- 配置視圖解析器,解析jsp,默認使用jstl標籤,所以需要導入jstl的相關jar包 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置前綴與後綴,這樣Controller返回的視圖名只用寫視圖文件的部分路徑加視圖文件名稱即可 -->
<!-- 解析視圖名時要添加的前綴 -->
<property name="prefix" value="/WEB-INF/"></property>
<!-- 解析視圖名時要添加的後綴 -->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 使用註解式 -->
<!-- 多個適配器或映射器可以共存 -->
<!-- 配置註解式處理器映射器
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
-->
<!-- 配置註解式處理器適配器
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
-->
<!-- 開啓註解,使用mvc的註解驅動,適配器以及映射器配置可以取消,即刪除上面的適配器以及映射器配置 -->
<!-- 開發時僅使用此配置即可,但需要開啓註解掃描,用來掃描帶有相關注解的類 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 開啓註解掃描 -->
<context:component-scan base-package="test"></context:component-scan>
</beans>
3. 通過註解編寫處理器(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.taotao.po.Items;
//通過@Controller註解標示該類是一個Controller處理器,括號內的字符串可以指定該類在Spring中作爲bean的id
@Controller("controller2")
public class Controller2 {
//@RequestMapping該註解標示該方法用於映射處理/findItems.action路徑傳來的請求
@RequestMapping("/findItems")
public ModelAndView findItems(){
List<Items> itemsList=new ArrayList<Items>();
//向list中填充數據
Items i1=new Items();
i1.setName("華爲手機");
i1.setPrice(3000f);
i1.setDetail("mate10");
i1.setId(1);
Items i2=new Items();
i2.setName("蘋果手機");
i2.setPrice(8888f);
i2.setDetail("蘋果10");
i2.setId(2);
itemsList.add(i1);
itemsList.add(i2);
//生成返回值
ModelAndView mav=new ModelAndView();
//相當於request.setAttribute(),在jsp頁面中通過itemsList獲取數據
mav.addObject("itemsList", itemsList);
//指定視圖
//原本的視圖文件路徑應寫爲mav.setViewName("/WEB-INF/jsp/itemsList.jsp");但在視圖解析器中配置了前綴和後綴,所以可以簡寫爲
mav.setViewName("jsp/itemsList");
return mav;
}
}
4. 編寫視圖文件:需要在對應的路徑下編寫jsp文件,並對傳來的Model數據進行處理
5. 調試跟蹤:在前端控制器的源碼中doDiapatch方法打斷點,通過前端控制器源碼分析springmvc的執行過程。
第一步:前端控制器接收請求,調用doDiapatch
第二步:前端控制器調用處理器映射器查找 Handler
第三步:調用處理器適配器執行Handler,得到執行結果ModelAndView
第四步:視圖渲染,將model數據填充到request域。視圖解析,得到view:
調用view的渲染方法,將model數據填充到request域,渲染方法: