Springmvc屬於表現層的框架,它是Spring框架的一部分。
Spring架構:
架構流程:
- 用戶發送請求至前端控制器DispatcherServlet
- DispatcherServlet收到請求調用HandlerMapping處理器映射器。
- 處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一併返回給DispatcherServlet。
- DispatcherServlet通過HandlerAdapter處理器適配器調用處理器
- 執行處理器(Controller,也叫後端控制器)。
- Controller執行完成返回ModelAndView
- HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet
- DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器
- ViewReslover解析後返回具體View
- DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中)。
- DispatcherServlet響應用戶
以下組件通常使用框架提供實現
DispatcherServlet:前端控制器
用戶請求到達前端控制器,它就相當於mvc模式中的c,dispatcherServlet是整個流程控制的中心,由它調用其它組件處理用戶的請求,dispatcherServlet的存在降低了組件之間的耦合性。
HandlerMapping:處理器映射器
HandlerMapping負責根據用戶請求url找到Handler即處理器,springmvc提供了不同的映射器實現不同的映射方式,例如:配置文件方式,實現接口方式,註解方式等。
Handler:處理器
Handler 是繼DispatcherServlet前端控制器的後端控制器,在DispatcherServlet的控制下Handler對具體的用戶請求進行處理。
由於Handler涉及到具體的用戶業務請求,所以一般情況需要程序員根據業務需求開發Handler。
HandlAdapter:處理器適配器
通過HandlerAdapter對處理器進行執行,這是適配器模式的應用,通過擴展適配器可以對更多類型的處理器進行執行。
ViewResolver:視圖解析器
View Resolver負責將處理結果生成View視圖,View Resolver首先根據邏輯視圖名解析成物理視圖名即具體的頁面地址,再生成View視圖對象,最後對View進行渲染將處理結果通過頁面展示給用戶。
View:視圖
springmvc框架提供了很多的View視圖類型的支持,包括:jstlView、freemarkerView、pdfView等。我們最常用的視圖就是jsp。
一般情況下通過頁面標籤或頁面模版技術將模型數據通過頁面展示給用戶,需要由程序員根據業務需求開發具體的頁面。
說明:在springmvc的各個組件中,處理器映射器、處理器適配器、視圖解析器稱爲springmvc的三大組件。需要用戶開發的組件有handler、view。
在web.xml中配置前端控制器
<!-- 配置SrpingMVC的前端控制器 -->
<servlet>
<servlet-name>springmvc-web</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc-web</servlet-name>
<!-- 配置所有以.action結尾的請求進入SpringMVC -->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
配置處理器映射器@ResquestMapping
註解式處理器映射器,對類中標記了@ResquestMapping的方法進行映射。根據@ResquestMapping定義的url匹配@ResquestMapping標記的方法,匹配成功返回HandlerMethod對象給前端控制器。
在class上添加@RequestMapping(url)指定通用請求前綴, 限制此類下的所有方法請求url必須以請求前綴開頭
除了可以對url進行設置,還可以限定請求進來的方法
限定POST:@RequestMapping(method = RequestMethod.POST)
限定: GET@RequestMapping(method = RequestMethod.GET)
同時限定:@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST})
Controller方法返回值
1.ModelAndView
controller方法中定義ModelAndView對象並返回,對象中可添加model數據、指定view
2.void
response指定響應結果:
使用request轉發頁面,如下:
request.getRequestDispatcher("頁面路徑").forward(request, response);
request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request, response);
可以通過response頁面重定向:
response.sendRedirect("url")
response.sendRedirect("/springmvc-web2/itemEdit.action");
可以通過response指定響應結果,例如響應json數據如下:
response.getWriter().print("{\"abc\":123}");//頁面顯示json
3.String
controller方法返回字符串可以指定邏輯視圖名,通過視圖解析器解析爲物理視圖地址。
return"itemList";//指定邏輯視圖名,經過視圖解析器解析爲jsp物理路徑:/WEB-INF/jsp/itemList.jsp
return"redirect:/itemEdit.action?itemId=" + item.getId();//重定向
return"forward:/itemEdit.action";//結果轉發到/editItem.action,request可以帶過去
註解驅動 <mvc:annotation-driven />
直接配置處理器映射器和處理器適配器比較麻煩,可以使用註解驅動來加載。
SpringMVC使用<mvc:annotation-driven>自動加載RequestMappingHandlerMapping和RequestMappingHandlerAdapter
可以在springmvc.xml配置文件中使用<mvc:annotation-driven>替代註解處理器和適配器的配置。
<!-- 註解驅動 -->
<mvc:annotation-driven />
視圖解析器
視圖解析器使用SpringMVC框架默認的InternalResourceViewResolver,這個視圖解析器支持JSP視圖解析
在springmvc.xml配置文件中配置如下:
<!-- Example: prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test" ->
"/WEB-INF/jsp/test.jsp" -->
<!-- 配置視圖解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置邏輯視圖的前綴 -->
<propertyname="prefix"value="/WEB-INF/jsp/"/>
<!-- 配置邏輯視圖的後綴 -->
<propertyname="suffix"value=".jsp"/>
</bean>
邏輯視圖名需要在controller中返回ModelAndView指定,比如返回的邏輯視圖名爲: return "ItemList";則最終返回的jsp視圖地址:
“WEB-INF/jsp/itemList.jsp”
最終jsp物理地址:前綴+邏輯視圖名+後綴
@RequestParam:使用@RequestParam常用於處理簡單類型的綁定。
value:參數名字,即入參的請求參數名字,如value=“itemId”表示請求的參數 區中的名字爲itemId的參數的值將傳入
required:是否必須,默認是true,表示請求中一定要有相應的參數,否則將報錯,TTP Status 400 - Required Integer parameter 'XXXX' is not present
defaultValue:默認值,表示如果請求中沒有同名參數時的默認值
springmvc解決post亂碼問題,在web.xml中配置
<!-- 解決post亂碼問題 -->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 設置編碼參是UTF8 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
對於get請求中文參數出現亂碼解決方法有兩個:
1.修改tomcat配置文件添加編碼與工程編碼一致,如下:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
2.對參數進行重新編碼:
String newUserName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默認編碼,需要將tomcat編碼後的內容按utf-8編碼
springmvc解決全局異常的方法:
https://blog.csdn.net/weixin_41987553/article/details/82355072
springmvc與struts2不同
- springmvc的入口是一個servlet即前端控制器,而struts2入口是一個filter過濾器。
- springmvc是基於方法開發(一個url對應一個方法),請求參數傳遞到方法的形參,可以設計爲單例或多例(建議單例),struts2是基於類開發,傳遞參數是通過類的屬性,只能設計爲多例。
- Struts採用值棧存儲請求和響應的數據,通過OGNL存取數據, springmvc通過參數解析器是將request請求內容解析,並給方法形參賦值,將數據和視圖封裝成ModelAndView對象,最後又將ModelAndView中的模型數據通過request域傳輸到頁面。Jsp視圖解析器默認使用jstl。
spring攔截器:新建一個類實現HandlerInterceptor接口(判斷登陸狀態,權限等用途)
publicclass HandlerInterceptor1 implements HandlerInterceptor {
// controller執行後且視圖返回後調用此方法
// 這裏可得到執行controller時的異常信息
// 這裏可記錄操作日誌
@Override
publicvoid afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("HandlerInterceptor1....afterCompletion");
}
// controller執行後但未返回視圖前調用此方法
// 這裏可在返回用戶前對模型數據進行加工處理,比如這裏加入公用信息以便頁面顯示
@Override
publicvoid postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("HandlerInterceptor1....postHandle");
}
// Controller執行前調用此方法
// 返回true表示繼續執行,返回false中止執行
// 這裏可以加入登錄校驗、權限攔截等
@Override
publicboolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("HandlerInterceptor1....preHandle");
// 設置爲true,測試使用
returntrue;
}
}
在springmvc.xml中配置攔截器
<!-- 配置攔截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 所有的請求都進入攔截器 -->
<mvc:mappingpath="/**"/>
<!-- 配置具體的攔截器 -->
<beanclass="cn.itcast.ssm.interceptor.HandlerInterceptor1"/>
</mvc:interceptor>
<mvc:interceptor>
<!-- 所有的請求都進入攔截器 -->
<mvc:mappingpath="/**"/>
<!-- 配置具體的攔截器 -->
<beanclass="cn.itcast.ssm.interceptor.HandlerInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors>