如何假裝成一個服務端開發(一)java
如何假裝成一個服務端開發(三) spring
如何假裝成一個服務端開發(五)json
如何假裝成一個服務端開發(七)服務器
關於mvc模式這裏就再也不詳細說明了,不過對應到Spring開發的流程仍是能夠學習一下的。mybatis
視圖發出http請求,發送給控制器(注意,這裏叫作Controller和咱們後面要說的Controller的意義有所不一樣)。控制器會進行請求的分發,最終到達模型層。而後模型層要麼進行服務要麼再繼續從數據庫取數據,而後返回給控制層,控制層再返回給前臺視圖。mvc
儘管在 Spring Boot 的開發中,咱們能夠很快速地經過配置實現 Spring MVC 的開發,但爲了解決實際的問題,咱們仍是頗有必要了解 Spring MVC 的運行流程和組件,不然很難理解 Spring Boot 自動爲咱們生成了什麼,配置了什麼,這些有什麼用。流程和組件是 Spring MVC 的核心,Spring MVC 的流程是圍繞 DispatcherServlet 而工做的,它負責協調和組織不一樣組件完成請求處理並返回響應工做。app
上圖是一張Spring MVC工做的標準流程圖,可是在進行這些流程以前,咱們還須要經歷相當重要的一步,服務器啓動。在Spring Boot的環境下,當服務器啓動,它就會初始化Spring MVC的一些重要組件,好比DispactherServlet HandlerAdapter等。咱們能夠在DispatcherServlet.properties 這個文件中找到被初始化的類,而且會存放在Spring IoC容器中。
# 國際化解析器 org.springframework.web.servlet.LocaleResolver= ... # 主題解析器 org.springframework.web.servlet.ThemeResolver=... # HandlerMapping 實例 org.springframework.web.servlet.HandlerMapping=... # 處理器適配器 org.springframework.web.servlet.HandlerAdapter=... # 處理器異常解析器 org.springframework.web.servlet.HandlerExceptionResolver=... # 策略視圖名稱轉換器,當你沒有返回視圖邏輯名稱的時候,經過它能夠生成默認的視圖名稱 org.springframework.web.servlet.RequestToViewNameTranslator=... # 視圖解析器 org.springframework.web.servlet.ViewResolver=... # FlashMap 管理器。不經常使用,再也不討論 org.springframework.web.servlet.FlashMapManager=...
另外,咱們在代碼中還會定義一些@Controller ,它表示這是一個控制器,好比咱們在上一節定義了一個控制器
@Controller @RequestMapping("/mybatis") public class MyBatisController { @Autowired private MyBatisUserService myBatisUserService = null; @RequestMapping("/getUser") @ResponseBody public User getUser(Long id) { return myBatisUserService.getUser(id); } @RequestMapping("/test") @ResponseBody public String test() { return "test"; } }
@RequestMapping表明請求路徑和控制器(和它其中的方法)的映射關係。前面看到在Spring MVC初始化的時候有一個HandlerMapping對象,這個對象會掃描全部的@RequestMapping而且保存起來。當用戶發起的請求被DispatcherServlet鏈接後,就會經過HandlerMapping進行匹配。匹配完成後,HandlerMapping會返回一個HandlerExecutionChain對象
public class HandlerExecutionChain { // 日誌 private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class); // 處理器 private final Object handler; // 攔截器數組 private HandlerInterceptor[] interceptors; // 攔截器列表 private List<HandlerInterceptor> interceptorList; // 攔截器當前下標 private int interceptorIndex = -1; ...... }
其中handler字段就是對@Controller的包裝,裏面包含了參數處理邏輯,攔截器處理邏輯等。
獲得這個匹配返回對象以後咱們須要去執行他,擔任執行者的就是HandlerAdapter,不一樣的handler可能有不一樣的執行邏輯,因此這個時候就會存在多個HandlerAdapter去執行操做。
拋開內部複雜的運行邏輯,從宏觀上來看,最終咱們的@Controller中的方法得以被執行,最終將返回一個ModelAndView(可是咱們在使用的時候可能會看到直接返回string,或者返回json字符的,咱們晚點再解釋,多數狀況最終仍是會被封裝成ModelAndView)。而後ModelAndView會傳入駛入解析器ViewResolver去生成(定位)最後的視圖,最終將視圖渲染出來。
在Spring Boot的默認初始化中,咱們可以看到默認的ViewResolver 的 InternalResourceViewResolver ,咱們能夠經過application.properties 配置前綴和後綴。
spring.mvc.view.prefix=/WEB-INF/jsp/ spring.mvc.view.suffix=.jsp
經過這個配置InternalResourceViewResolver 這個視圖解析器解析時就會添加前綴和後綴。好比控制器返回 "/user/details"就會添加先後綴而後定位視圖。
一下列出了Spring MVC的可配置項
# SPRING MVC (WebMvcProperties) spring.mvc.async.request-timeout= # 異步請求超時時間(單位爲毫秒) spring.mvc.contentnegotiation.favor-parameter=false # 是否使用請求參數(默認參數爲"format")來肯定請求的媒體類型 spring.mvc.contentnegotiation.favor-path-extension=false # 是否使用 URL 中的路徑擴展來肯定請求的媒體類型 spring.mvc.contentnegotiation.media-types.*= # 設置內容協商向媒體類型映射文件擴展名。例如,YML 文本/YAML spring.mvc.contentnegotiation.parameter-name= # 當啓用 favor-parameter 參數是,自定義參數名 spring.mvc.date-format= # 日期格式配置,如 yyyy-MM-dd spring.mvc.dispatch-trace-request=false # 是否讓FrameworkServlet doService方法支持 TRACE 請求 spring.mvc.dispatch-options-request=true # 是否啓用 FrameworkServlet doService 方法支持OPTIONS 請求 spring.mvc.favicon.enabled=true # spring MVC 的圖標是否啓用 spring.mvc.formcontent.putfilter.enabled=true # Servlet 規範要求表格數據可用於 HTTP POST 而不是 HTTP PUT 或 PATCH 請求,這個選項將使得過濾器攔截 HTTP PUT 和 PATCH,且內容類型是 application/x-www-form-urlencoded 的請求,而且將其轉換爲 POST 請求 spring.mvc.ignore-default-model-on-redirect=true # 若是配置爲 default,那麼它將忽略模型重定向的場景 spring.mvc.locale= # 默認國際化選項,默認取 Accept-Language spring.mvc.locale-resolver=accept-header # 國際化解析器,若是須要固定可使用 fixed spring.mvc.log-resolved-exception=false # 是否啓用警告日誌異常解決 spring.mvc.message-codes-resolver-format= # 消息代碼的格式化策略。例如,' prefix_error_code ' spring.mvc.pathmatch.use-registered-suffix-pattern=false # 是否對 spring.mvc.contentnegotiation.media-types.*註冊的擴展采用後綴模式匹配 spring.mvc.pathmatch.use-suffix-pattern=false # 當匹配模式到請求時,是否使用後綴模式匹配(.*) spring.mvc.servlet.load-on-startup=-1 # 啓用 Spring Web 服務 Serlvet 的優先順序配置 spring.mvc.static-path-pattern=/** # 指定靜態資源路徑 spring.mvc.throw-exception-if-no-handler-found=false # 若是請求找不處處理器,是否拋出 NoHandlerFoundException 異常 spring.mvc.view.prefix= # Spring MVC 視圖前綴 spring.mvc.view.suffix= # Spring MVC 視圖後綴
咱們能夠在application.properties中直接配置。這是經過Spring Boot 提供的WebMvcAutoConfiguration類實現的,這個類中有一個靜態內部類WebMvcAutoConfigurationAdapter,它繼承了WebMvcConfigurer。
而 WebMvcConfigurer 正是Spring MVC用於配置的接口,在沒有Spring Boot的狀況下,咱們會重寫這個接口(接口中有不少default方法,因此沒必要重寫全部方法),添加咱們須要的攔截器等便可。可是在Spring Boot中,因爲自動配置的存在,咱們的配置會更簡單一些。
因此Spring MVC的主要工做就是攔截http請求,而且將根據必定規則將請求分發至對應的方法處理。實際上Spring MVC還有很是多的東西能夠學習,可是基本上全部內容都是牢牢圍繞這個目標進行的。
Spring MVC還能作那些事情?
1.處理器映射。 咱們可以制定攔截POST 或者GET等請求方式,限定請求參數,限定請求頭等,具體能夠學習@RequestMapping 和 @GetMapping等註解
2.參數獲取。Spring MVC是如何從請求中獲取數據的而且轉換成@Controller中的參數的
3.自定義參數轉換規則。Spring MVC默認提供了一些轉換規則,可是並不能知足全部狀況,不少時候須要咱們本身定義轉換的規則.
4.Spring MVC 將參數轉換出來以後提供了參數合法性驗證的能力。
5.ModelAndView和ViewResolver學習,默認支持輸出pdf,excel文檔等能力
6.Spring MVC對文件上傳的支持
7.在執行@Controller方法以前以後,完成後還能夠設置攔截器。
8.Spring MVC 國際化(語言切換)使用
9.Spring MVC 操做Session
10.Spring MVC 獲取請求頭
11.@ResponseBody
12.重定向
13.@Controller 的運行通知
上面列出的這些只是想總結一下Spring MVC還可以作那些東西,咱們並不着急一次學全,在理解Spring MVC運行邏輯的狀況下,其餘知識內容咱們能夠在須要的時候慢慢學習補充。