Spring MVC的工作原理
Spring MVC的工作原理如下:
- DispatcherServlet 接收用戶的請求
- 找到用于處理request的 handler 和 Interceptors,構造成 HandlerExecutionChain 執行鏈
- 找到 handler 相對應的 HandlerAdapter
- 執行所有注冊攔截器的preHandler方法
- 調用 HandlerAdapter 的 handle() 方法處理請求,返回 ModelAndView
- 倒序執行所有注冊攔截器的postHandler方法
- 請求視圖解析和視圖渲染
Spring MVC的主要組件?
- 前端控制器(DispatcherServlet):接收用戶請求,給用戶返回結果。
- 處理器映射器(HandlerMapping):根據請求的url路徑,通過注解或者xml配置,尋找匹配的Handler。
- 處理器適配器(HandlerAdapter):Handler 的適配器,調用 handler 的方法處理請求。
- 處理器(Handler):執行相關的請求處理邏輯,并返回相應的數據和視圖信息,將其封裝到ModelAndView對象中。
- 視圖解析器(ViewResolver):將邏輯視圖名解析成真正的視圖View。
- 視圖(View):接口類,實現類可支持不同的View類型(JSP、FreeMarker、Excel等)。
Spring MVC的常用注解由有哪些?
- @Controller:用于標識此類的實例是一個控制器。
- @RequestMapping:映射Web請求(訪問路徑和參數)。
- @ResponseBody:注解返回數據而不是返回頁面
- @RequestBody:注解實現接收 http 請求的 json 數據,將 json 數據轉換為 java 對象。
- @PathVariable:獲得URL中路徑變量中的值
- @RestController:@Controller+@ResponseBody
- @ExceptionHandler標識一個方法為全局異常處理的方法。
@Controller 注解有什么用?
@Controller
?注解標記一個類為 Spring Web MVC 控制器。Spring MVC 會將掃描到該注解的類,然后掃描這個類下面帶有?@RequestMapping
?注解的方法,根據注解信息,為這個方法生成一個對應的處理器對象,在上面的 HandlerMapping 和 HandlerAdapter組件中講到過。
當然,除了添加?@Controller
?注解這種方式以外,你還可以實現 Spring MVC 提供的?Controller
?或者?HttpRequestHandler
?接口,對應的實現類也會被作為一個處理器對象
@RequestMapping 注解有什么用?
@RequestMapping
?注解,用于配置處理器的 HTTP 請求方法,URI等信息,這樣才能將請求和方法進行映射。這個注解可以作用于類上面,也可以作用于方法上面,在類上面一般是配置這個控制器的 URI 前綴。
@RestController 和 @Controller 有什么區別?
@RestController
?注解,在?@Controller
?基礎上,增加了?@ResponseBody
?注解,更加適合目前前后端分離的架構下,提供 Restful API ,返回 JSON 數據格式。
@RequestMapping 和 @GetMapping 注解有什么不同?
@RequestMapping
:可注解在類和方法上;@GetMapping
?僅可注冊在方法上@RequestMapping
:可進行 GET、POST、PUT、DELETE 等請求方法;@GetMapping
?是?@RequestMapping
?的 GET 請求方法的特例。
@RequestParam 和 @PathVariable 兩個注解的區別
兩個注解都用于方法參數,獲取參數值的方式不同,@RequestParam
?注解的參數從請求攜帶的參數中獲取,而?@PathVariable
?注解從請求的 URI 中獲取
@RequestBody和@RequestParam的區別
@RequestBody一般處理的是在ajax請求中聲明contentType: "application/json; charset=utf-8"時候。也就是json數據或者xml數據。
@RequestParam一般就是在ajax里面沒有聲明contentType的時候,為默認的x-www-form-urlencoded
格式時。
Spring MVC的異常處理
可以將異常拋給Spring框架,由Spring框架來處理;我們只需要配置簡單的異常處理器,在異常處理器中添視圖頁面即可。
- 使用系統定義好的異常處理器 SimpleMappingExceptionResolver
- 使用自定義異常處理器
- 使用異常處理注解
SpringMVC 用什么對象從后臺向前臺傳遞數據的?
- 將數據綁定到 request;
- 返回 ModelAndView;
- 通過ModelMap對象,可以在這個對象里面調用put方法,把對象加到里面,前端就可以通過el表達式拿到;
- 綁定數據到 Session中。
SpringMvc的Controller是不是單例模式?
單例模式。在多線程訪問的時候有線程安全問題,解決方案是在控制器里面不要寫可變狀態量,如果需要使用這些可變狀態,可以使用ThreadLocal,為每個線程單獨生成一份變量副本,獨立操作,互不影響。
介紹下 Spring MVC 攔截器?
Spring MVC 攔截器對應HandlerInterceor接口,該接口位于org.springframework.web.servlet的包中,定義了三個方法,若要實現該接口,就要實現其三個方法:
- 前置處理(preHandle()方法):該方法在執行控制器方法之前執行。返回值為Boolean類型,如果返回false,表示攔截請求,不再向下執行,如果返回true,表示放行,程序繼續向下執行(如果后面沒有其他Interceptor,就會執行controller方法)。所以此方法可對請求進行判斷,決定程序是否繼續執行,或者進行一些初始化操作及對請求進行預處理。
- 后置處理(postHandle()方法):該方法在執行控制器方法調用之后,且在返回ModelAndView之前執行。由于該方法會在DispatcherServlet進行返回視圖渲染之前被調用,所以此方法多被用于處理返回的視圖,可通過此方法對請求域中的模型和視圖做進一步的修改。
- 已完成處理(afterCompletion()方法):該方法在執行完控制器之后執行,由于是在Controller方法執行完畢后執行該方法,所以該方法適合進行一些資源清理,記錄日志信息等處理操作。
可以通過攔截器進行權限檢驗,參數校驗,記錄日志等操作
SpringMvc怎么配置攔截器?
有兩種寫法,一種是實現HandlerInterceptor接口,另外一種是繼承適配器類,接著在接口方法當中,實現處理邏輯;然后在SpringMvc的配置文件中配置攔截器即可:
<!-- 配置SpringMvc的攔截器 -->
<mvc:interceptors><bean id="myInterceptor" class="com.dabin.MyHandlerInterceptor"></bean><!-- 只攔截部分請求 --><mvc:interceptor><mvc:mapping path="/xxx.do" /><bean class="com.dabin.MyHandlerInterceptorAdapter" /></mvc:interceptor>
</mvc:interceptors>
Spring MVC 的攔截器和 Filter 過濾器有什么差別?
有以下幾點:
- 功能相同:攔截器和 Filter 都能實現相應的功能
- 容器不同:攔截器構建在 Spring MVC 體系中;Filter 構建在 Servlet 容器之上
- 使用便利性不同:攔截器提供了三個方法,分別在不同的時機執行;過濾器僅提供一個方法
什么是REST?
REST,英文全稱,Resource Representational State Transfer,對資源的訪問狀態的變化通過url的變化表述出來。
Resource:資源。資源是REST架構或者說整個網絡處理的核心。
Representational:某種表現形式,比如用JSON,XML,JPEG等。
State Transfer:狀態變化。通過HTTP method實現。
REST描述的是在網絡中client和server的一種交互形式。用大白話來說,就是通過URL就知道要什么資源,通過HTTP method就知道要干什么,通過HTTP status code就知道結果如何。
舉個例子:
GET /tasks 獲取所有任務
POST /tasks 創建新任務
GET /tasks/{id} 通過任務id獲取任務
PUT /tasks/{id} 更新任務
DELETE /tasks/{id} 刪除任務
GET代表獲取一個資源,POST代表添加一個資源,PUT代表修改一個資源,DELETE代表刪除一個資源。
server提供的RESTful API中,URL中只使用名詞來指定資源,原則上不使用動詞。用HTTP Status Code
傳遞server的狀態信息。比如最常用的 200 表示成功,500 表示Server內部錯誤等。
使用REST有什么優勢呢?
第一,風格統一了,不會出現delUser/deleteUser/removeUser
各種命名的代碼了。
第二,面向資源,一目了然,具有自解釋性。
第三,充分利用 HTTP 協議本身語義。
SpringMVC怎么樣設定重定向和轉發的?
(1)轉發:在返回值前面加"forward:",例如"forward:user.do?name=method4"
(2)重定向:在返回值前面加"redirect:",例如"redirect:http://www.baidu.com"