Spring MVC 的請求處理流程

DispatcherServlet
DispatcherServlet繼承結構

DispatcherServlet對請求的處理流程
大致步驟
- 綁定?些 Attribute
-
- WebApplicationContext / LocaleResolver / ThemeResolver
- 處理 Multipart
-
- 如果是,則將請求轉為 MultipartHttpServletRequest
- Handler 處理
-
- 如果找到對應 Handler,執(zhí)? Controller 及前后置處理器邏輯
- 處理返回的 Model ,呈現(xiàn)(render)視圖
具體可以參見DispatcherServlet#doService(...)和DispatcherServlet#doDispatch(...)方法
如何定義處理?法(即Handler方法)
定義映射關系
- @Controller
- @RequestMapping
-
- value: 指定請求的實際地址, 比如 /action/info之類
- method: 指定請求的method類型, GET、POST、PUT、DELETE等
- consumes: 指定處理請求的提交內容類型(Content-Type),例如application/json, text/html;
- produces: 指定返回的內容類型,僅當request請求頭中的(Accept)類型中包含該指定類型才返回
- params: 指定request中必須包含某些參數(shù)值是,才讓該方法處理
- headers: 指定request中必須包含/不包含某些指定的header值,才能讓該方法處理請求
- @RestController
- @GetMapping / @PostMapping / @PutMapping / @DeleteMapping / @PatchMapping
定義處理?法
- @RequestBody / @ResponseBody / @ResponseStatus(用于改變HTTP響應的狀態(tài)碼)
- @PathVariable / @RequestParam / @RequestHeader
-
- 通過@PathVariable 可以將URL中占位符參數(shù){xxx}綁定到處理器類的方法形參中@PathVariable(“xxx“)
- @RequestParam標注在接口的方法參數(shù)上,被標注的參數(shù)的值來源于request.getParameter或request.getParameterValues
- @RequestHeader注解,能夠將請求頭中的變量值映射到控制器的參數(shù)中。
- HttpEntity / RequestEntity / ResponseEntity
-
- HttpEntity表示http的request和resposne實體,它由消息頭和消息體組成。從HttpEntity中可以獲取http請求頭和回應頭,也可以獲取http請求體和回應體信息。HttpEntity的典型應用是配合RestTemplate。
詳細參數(shù)
https://docs.spring.io/spring-framework/docs/5.1.5.RELEASE/spring-framework-reference/web.html#mvc-ann-arguments
詳細返回
https://docs.spring.io/spring-framework/docs/5.1.5.RELEASE/spring-framework-reference/web.html#mvc-ann-return-types
?法示例

定義類型轉換
SpringBoot的默認實現(xiàn)
在WebMvcAutoConfiguration的內部類
WebMvcAutoConfigurationAdapter中實現(xiàn)了重寫WebMvcConfigurer接口這樣一個方法。
addFormatters方法用于添加默認的{@link Converter Converter}和{@link Formatter Formatters}到注冊中心。

ApplicationConversionService#addBeans(...)方法

Converter和Formatter的異同
兩者的作用一樣,都是類型轉換。
org.springframework.format.Formatter只能做String類型到其他類型的轉換。
org.springframework.core.convert.converter.Converter可以做任意類型的轉換。
??實現(xiàn) WebMvcConfigurer
- 添加?定義的 Converter
- 添加?定義的 Formatter

定義校驗
- 通過 Validator 對綁定結果進?校驗
-
- Hibernate Validator
- @Valid、@Validated注解 及自定義注解校驗
- BindingResult (對于不希望Spring MVC來介入我的Valid失敗后的操作,可以通過BindingResult實現(xiàn))
Multipart 上傳
- 配置 MultipartResolver
-
- Spring Boot ?動配置 MultipartAutoConfiguration
- ?持類型 multipart/form-data
- MultipartFile 類型

一些誤區(qū)/注意點
@RequestParam注解能讀取請求體里的內容嗎?
@RequestParam:In Spring MVC, "request parameters" map to query parameters, form data, and parts in multipart requests.
有時候我們只想取出請求body里面的部分內容,但@RequstBody注解是把整個請求的Body傳給參數(shù),而RequestParam是可以把Body里的對應部分取出來傳給參數(shù)。
controller里面可以實現(xiàn)傳多個對象么? 比如:hello(Student student, Teacher teacher)
注意:@RequestBody只能將一個請求報文體轉成一個復雜對象。
- 將多個對象合成一個中間復雜對象,之后再拆開。
- 通過 Map 或者Jackson 的 ObjectNode
- 自定義注解,并將它注冊到 Spring MVC