一、什么是SpringMVC?
1.SpringMVC 是一種基於 Java 的實現 MVC 設計模型的請求驅動類型的輕量級 Web 框架,屬於SpringFrameWork的后續產品,已經融合在 Spring Web Flow 中。
2.SpringMVC = Spring +MVC
- spring mvc類似於struts的一個MVC開框架,其實都是屬於spring,spring mvc需要有spring的架包作為支撐才能跑起來.
spring是一個一站式的框架,提供了表現層(springmvc)到業務層(spring)再到數據層(springdata)的全套解決方案;spring的兩大核心IOC(控制反轉)和AOP(面向切面編程)更是給我們的程序解耦和代碼的簡介提供了支持。
Spring框架圖:
從Spring的結構圖可以看出,springMVC位於spring web端的一個框架,是一種基於Java的實現了Web MVC設計模式的請求驅動類型的輕量級Web框架,即使用了MVC架構模式的思想,將web層進行職責解耦。附:基於請求驅動指的就是使用請求-響應模型。
從名字上就可以窺探出,Spring>SpringMVC,那么事實上,spring和SpringMVC是一種父子關系。SpringMVC是spring擴展出的一個應用於web端的框架。在這里需要注意的一點,就是到底什么是父子容器關系:
spring主要的作用是黏合其他模塊組件,進行統一管理,springmvc則主要是負責web端。那么,我們都知道,我們在應用spring的時候,可以使用注入。這個時候,如果我們的web端是用的SpringMVC,這個時候,controller理論上是通過SpringMVC去注入,但是,使用spring注入,同樣是可行的。同理,service等層,使用SpringMVC配置的統一掃描裝配也是可以的。所以,如果說只是為了使用spring的依賴注入,是大可不必將springMVC和spring同時使用的。他們完全可以分開!
但是,盡管SpringMVC和spring都可以進行自動裝配掃描,值得注意的是:spring(父容器)並不能直接訪問SpringMVC(子容器)所注入的對象,但是SpringMVC卻可以訪問到spring裝載的對象。所以,在配置自動裝配的時候,應該注意到這一點。
- MVC
概念:
M:Model,模型。JavaBean
* 完成具體的業務操作,如:查詢數據庫,封裝對象
V:View,視圖。JSP
* 展示數據
C:Controller,控制器。Servlet
* 獲取用戶的輸入
* 調用模型
* 將數據交給視圖進行展示
二、SpringMVC的組件解析、執行流程
1.組件解析
2.springmvc的流程:
1、 用戶發送請求至前端控制器DispatcherServlet;
2、DispatcherServlet收到請求調用HandlerMapping處理器映射器;
3、處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一並返回給DispatcherServlet;
4、DispatcherServlet通過HandlerAdapter處理器適配器調用處理器,執行處理器(Controller,也叫后端控制器);
5、Controller執行完成返回ModelAndView,並返回給HandlerAdapter,HandlerAdapter將結果返回給DispatcherServlet;
6、DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器,ViewReslover解析后返回具體View給DispatcherServlet;
7、DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中)后返回給給客戶
3.組件
1、前端控制器DispatcherServlet(不需要攻城獅開發),由框架提供
作用:接收請求,響應結果,相當於轉發器,中央處理器。有了dispatcherServlet減少了其它組件之間的耦合度。
用戶請求到達前端控制器,它就相當於mvc模式中的c,dispatcherServlet是整個流程控制的中心,由它調用其它組件處理用戶的請求,dispatcherServlet的存在降低了組件之間的耦合性。
2、處理器映射器HandlerMapping(不需要攻城獅開發),由框架提供
作用:根據請求的url查找Handler
HandlerMapping負責根據用戶請求找到Handler即處理器,springmvc提供了不同的映射器實現不同的映射方式,例如:配置文件方式,實現接口方式,注解方式等。
3、處理器適配器HandlerAdapter
作用:按照特定規則(HandlerAdapter要求的規則)去執行Handler
通過HandlerAdapter對處理器進行執行,這是適配器模式的應用,通過擴展適配器可以對更多類型的處理器進行執行。
4、處理器Handler(需要攻城獅開發)
注意:編寫Handler時按照HandlerAdapter的要求去做,這樣適配器才可以去正確執行Handler
Handler 是繼DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler對具體的用戶請求進行處理。
由於Handler涉及到具體的用戶業務請求,所以一般情況需要攻城獅根據業務需求開發Handler。
5、視圖解析器View resolver(不需要攻城獅開發),由框架提供
作用:進行視圖解析,根據邏輯視圖名解析成真正的視圖(view)
View Resolver負責將處理結果生成View視圖,View Resolver首先根據邏輯視圖名解析成物理視圖名即具體的頁面地址,再生成View視圖對象,最后對View進行渲染將處理結果通過頁面展示給用戶。 springmvc框架提供了很多的View視圖類型,包括:jstlView、freemarkerView、pdfView等。
一般情況下需要通過頁面標簽或頁面模版技術將模型數據通過頁面展示給用戶,需要由攻城獅根據業務需求開發具體的頁面。
6、視圖View(需要攻城獅開發jsp...)
View是一個接口,實現類支持不同的View類型(jsp、freemarker、pdf...)
2.文件配置
web.xml:
<!--mvc核心控制器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
springmvc.xml:
<beans> <!-- 配置映射處理器:根據bean(自定義Controller)的name屬性的url去尋找handler;springmvc默認的映射處理器是BeanNameUrlHandlerMapping--> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean> <!-- 配置處理器適配器來執行Controller ,springmvc默認的是SimpleControllerHandlerAdapter --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean> <!-- 配置自定義Controller --> <bean id="myController" name="/hello.do" class="org.controller.MyController"></bean> <!-- 配置sprigmvc視圖解析器:解析邏輯視圖; 后台返回邏輯視圖:index 視圖解析器解析出真正物理視圖:前綴+邏輯視圖+后綴====/WEB-INF/jsps/index.jsp --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsps/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
詳圖:
三、SpringMVC常用注解
1.@RequestMapping
RequestMapping是一個用來處理請求地址映射的注解,可用於類或方法上。用於類上,表示類中的所有響應請求的方法都是以該地址作為父路徑。
RequestMapping注解有六個屬性,下面我們把她分成三類進行說明(下面有相應示例)。
1、 value, method;
value: 指定請求的實際地址,指定的地址可以是URI Template 模式(后面將會說明);
method: 指定請求的method類型, GET、POST、PUT、DELETE等;
2、consumes,produces
consumes: 指定處理請求的提交內容類型(Content-Type),例如application/json, text/html;
produces: 指定返回的內容類型,僅當request請求頭中的(Accept)類型中包含該指定類型才返回;
3、params,headers
params: 指定request中必須包含某些參數值是,才讓該方法處理。
headers: 指定request中必須包含某些指定的header值,才能讓該方法處理請求。
2.@Resource和@Autowired
@Resource和@Autowired都是做bean的注入時使用,其實@Resource並不是Spring的注解,它的包是javax.annotation.Resource,需要導入,但是Spring支持該注解的注入。
1、共同點
兩者都可以寫在字段和setter方法上。兩者如果都寫在字段上,那么就不需要再寫setter方法。
2、不同點
(1)@Autowired
@Autowired為Spring提供的注解,需要導入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
public class TestServiceImpl {
// 下面兩種@Autowired只要使用一種即可
@Autowired
private UserDao userDao; // 用於字段上
@Autowired
public void setUserDao(UserDao userDao) { // 用於屬性的方法上
this.userDao = userDao;
}
}
@Autowired注解是按照類型(byType)裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許null值,可以設置它的required屬性為false。如果我們想使用按照名稱(byName)來裝配,可以結合@Qualifier注解一起使用。如下:
public class TestServiceImpl {
@Autowired
@Qualifier("userDao")
private UserDao userDao;
}
(2)@Resource
@Resource默認按照ByName自動注入,由J2EE提供,需要導入包javax.annotation.Resource。@Resource有兩個重要的屬性:name和type,而Spring將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。所以,如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。如果既不制定name也不制定type屬性,這時將通過反射機制使用byName自動注入策略。
public class TestServiceImpl {
// 下面兩種@Resource只要使用一種即可
@Resource(name="userDao")
private UserDao userDao; // 用於字段上
@Resource(name="userDao")
public void setUserDao(UserDao userDao) { // 用於屬性的setter方法上
this.userDao = userDao;
}
}
注:最好是將@Resource放在setter方法上,因為這樣更符合面向對象的思想,通過set、get去操作屬性,而不是直接去操作屬性。
@Resource裝配順序:
①如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常。
②如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常。
③如果指定了type,則從上下文中找到類似匹配的唯一bean進行裝配,找不到或是找到多個,都會拋出異常。
④如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始類型進行匹配,如果匹配則自動裝配。
@Resource的作用相當於@Autowired,只不過@Autowired按照byType自動注入。
3.@ModelAttribute和 @SessionAttributes
代表的是:該Controller的所有方法在調用前,先執行此@ModelAttribute方法,可用於注解和方法參數中,可以把這個@ModelAttribute特性,應用在BaseController當中,所有的Controller繼承BaseController,即可實現在調用Controller時,先執行@ModelAttribute方法。
@SessionAttributes即將值放到session作用域中,寫在class上面。
具體示例參見下面:使用 @ModelAttribute 和 @SessionAttributes 傳遞和保存數據
4.@PathVariable
用於將請求URL中的模板變量映射到功能處理方法的參數上,即取出uri模板中的變量作為參數。如:
@Controller
public class TestController {
@RequestMapping(value="/user/{userId}/roles/{roleId}",method = RequestMethod.GET)
public String getLogin(@PathVariable("userId") String userId,
@PathVariable("roleId") String roleId){
System.out.println("User Id : " + userId);
System.out.println("Role Id : " + roleId);
return "hello";
}
@RequestMapping(value="/product/{productId}",method = RequestMethod.GET)
public String getProduct(@PathVariable("productId") String productId){
System.out.println("Product Id : " + productId);
return "hello";
}
@RequestMapping(value="/javabeat/{regexp1:[a-z-]+}",
method = RequestMethod.GET)
public String getRegExp(@PathVariable("regexp1") String regexp1){
System.out.println("URI Part 1 : " + regexp1);
return "hello";
}
}
5.@requestParam
@requestParam主要用於在SpringMVC后台控制層獲取參數,類似一種是request.getParameter("name"),它有三個常用參數:defaultValue = "0", required = false, value = "isApp";defaultValue 表示設置默認值,required 銅過boolean設置是否是必須要傳入的參數,value 值表示接受的傳入的參數類型。
6.@ResponseBody
作用: 該注解用於將Controller的方法返回的對象,通過適當的HttpMessageConverter轉換為指定格式后,寫入到Response對象的body數據區。
使用時機:返回的數據不是html標簽的頁面,而是其他某種格式的數據時(如json、xml等)使用;
四、SpringMVC的文件上傳
1.文件上傳的原理
2.單文件上傳
3.多文件上傳
五、SpringMVC的攔截器


1 <!--配置權限攔截器--> 2 <mvc:interceptors> 3 <mvc:interceptor> 4 <!--配置對哪些資源執行攔截操作--> 5 <mvc:mapping path="/**"/> 6 <!--配置哪些資源排除攔截操作--> 7 <mvc:exclude-mapping path="/user/login"/> 8 <bean class="com.itheima.interceptor.PrivilegeInterceptor"/> 9 </mvc:interceptor> 10 </mvc:interceptors>
六、SpringMVC異常處理機制
1.異常處理的思路
2 異常處理兩種方式
① 使用Spring MVC提供的簡單異常處理器SimpleMappingExceptionResolver;
② 實現Spring的異常處理接口HandlerExceptionResolver 自定義自己的異常處理器 。
1.簡單異常處理器SimpleMappingExceptionResolver
SpringMVC已經定義好了該類型轉換器,在使用時可以根據項目情況進行相應異常與視圖的映射配置
1 <!--配置簡單映射異常處理器--> 2 <bean class=“org.springframework.web.servlet.handler.SimpleMappingExceptionResolver”> 3 <property name=“defaultErrorView” value=“error”/> 默認錯誤視圖 4 <property name=“exceptionMappings”> 5 <map> 異常類型 錯誤視圖 6 <entry key="com.itheima.exception.MyException" value="error"/> 7 <entry key="java.lang.ClassCastException" value="error"/> 8 </map> 9 </property> 10 </bean>
2.自定義異常處理步驟
①創建異常處理器類實現HandlerExceptionResolver
1 public class MyExceptionResolver implements HandlerExceptionResolver { 2 @Override 3 public ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) { 4 //處理異常的代碼實現 5 //創建ModelAndView對象 6 ModelAndView modelAndView = new ModelAndView(); 7 modelAndView.setViewName("exceptionPage"); 8 return modelAndView; 9 } 10 }
②配置異常處理器
1 <bean id="exceptionResolver" 2 class="com.itheima.exception.MyExceptionResolver"/>