1:整體流程
1、用戶發送請求到前端控制器(DispatcherServlet)。
2、前端控制器請求處理器映射器(HandlerMapping)去查找處理器(Handler)。
3、找到以後處理器映射器(HandlerMappering)向前端控制器返回執行鏈(HandlerExecutionChain)。
4、前端控制器(DispatcherServlet)調用處理器適配器(HandlerAdapter)去執行處理器(Handler)。
5、處理器適配器去執行Handler。
6、處理器執行完給處理器適配器返回ModelAndView。
7、處理器適配器向前端控制器返回ModelAndView。
8、前端控制器請求視圖解析器(ViewResolver)去進行視圖解析。
9、視圖解析器向前端控制器返回View。
10、前端控制器對視圖進行渲染。
11、前端控制器向用戶響應結果。
2:主要組件
(1)前端控制器 DispatcherServlet(不需要程序員開發)
作用:接收請求、響應結果相當於轉發器,有了DispatcherServlet 就減少了其它組件之間的耦合度。
(2)處理器映射器HandlerMapping(不需要程序員開發)
作用:根據請求的URL來查找Handler
(3)處理器適配器HandlerAdapter
注意:在編寫Handler的時候要按照HandlerAdapter要求的規則去編寫,這樣適配器HandlerAdapter纔可以正確的去執行Handler。
(4)處理器Handler(需要程序員開發)
要實現重定向或者請求轉發時,只需要將方法的返回值設置爲String,return “redirect:路徑名”
(5)視圖解析器 ViewResolver(不需要程序員開發)
作用:進行視圖的解析 根據視圖邏輯名解析成真正的視圖(view)
(6)視圖View(需要程序員開發jsp)
View是一個接口, 它的實現類支持不同的視圖類型(jsp,freemarker,pdf等等)
3:攔截器和過濾器
過濾器依賴於servlet容器。在實現上基於函數回調,可以對幾乎所有請求進行過濾,但是缺點是一個過濾器實例只能在容器初始化時調用一次。使用過濾器的目的是用來做一些過濾操作,獲取我們想要獲取的數據. 比如:在過濾器中修改字符編碼;在過濾器中修改 HttpServletRequest的一些參數,包括:過濾低俗文字、危險字符等
攔截器依賴於web框架,在SpringMVC中就是依賴於SpringMVC框架。在實現上基於Java的反射機制,屬於面向切面編程(AOP)的一種運用。由於攔截器是基於web框架的調用.因此可以使用spring的依賴注入(DI)進行一些業務操作,同時一個攔截器實例在一個controller生命週期之內可以多次調用。但是缺點是隻能對controller請求進行攔截,對其他的一些比如直接訪問靜態資源的請求則沒辦法進行攔截處理。
攔截器可以通過實現HandlerInterceptor接口,重寫其中的preHandle(作用在Handle之前),postHandle(作用在Handle之後,視圖解析器之前),afteCompletion(作用在視圖解析器之後)三個方法。當只有一個攔截器的時候執行順序是:preHandle-》Handle-》postHandle-》視圖解析器-》afteCompletion。當有多個攔截器的時候,與他們在spring mvc配置的先後順序相關,假如interceptor1配置在interceptor2之前。則執行順序爲:preHandle1-》preHandle1-》Handle-》postHandle2-》-》postHandle2-1-》視圖解析器-》afteCompletion2-》afteCompletion1。即preHandle是按照配置先後順序,而postHandle和afteCompletion是配置順序的相反順序。
過濾器的運行是依賴於servlet容器的,跟springmvc等框架並沒有關係。並且多個過濾器的執行順序跟web.xml文件中定義的先後關係有關。
攔截器的執行順序跟在SpringMVC的配置文件中定義的先後順序有關。
4:統一異常處理
系統的dao、service、controller出現都通過throwsException向上拋出,最後由springmvc前端控制器交由異常處理器進行異常處理,如下圖:
全局異常處理器處理思路:
解析出異常類型
如果該異常類型是系統 自定義的異常,直接取出異常信息,在錯誤頁面展示
如果該異常類型不是系統 自定義的異常,構造一個自定義的異常類型(信息爲“未知錯誤”)
5:解決post和get的中文亂碼問題
1)解決post請求亂碼問題:
在web.xml中加入:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(2)get請求中文參數出現亂碼解決方法有兩個:
①修改tomcat配置文件添加編碼與工程編碼一致,如下:
<ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
②另外一種方法對參數進行重新編碼:
String userName= new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默認編碼,需要將tomcat編碼後的內容按utf-8編碼。