1. 程式人生 > >Spring 實戰 Web 二: Spring MVC 的高階技術

Spring 實戰 Web 二: Spring MVC 的高階技術

自定義 DispatcherServlet 的配置

通過 AbstractAnnotationConfigDispatcherServletInitializer 可以實現通過 Java 來配置 Spring MVC,其中有三個方法是必須進行覆寫的:getRootConfigClasses、getServletConfigClasses、getServletMappings,實際上除了這三個方法外,還有很多方法是可以進行重寫的:
1. customizeRegistration
DispatcherServlet 被註冊到 Servlet 容器後,就會呼叫 customizeRegistration 方法,並將註冊後得到的 ServletRegistration.Dynamic 物件傳遞過來,通過該物件可對 DispatcherServlet 進行一些定製,如:setLoadOnStartup、setMultipartConfig、setInitParameter 等
image.png

新增 Filter、Servlet 和 Listener

繼承 AbstractAnnotationConfigDispatcherServletInitializer 會建立 DispatcherServlet 和 ContextLoaderListener,如果想註冊其他元件,只需實現 WebApplicationInitializer 介面即可。
image.png

multipart 形式資料

配置 multipart 解析器

Spring 3.1 開始,內建了兩個 multipart 解析器:
1. CommonsMultipartResolver,使用 Jakarta Commons FileUpload 解析 multipart 請求
2. StandardServletMultipartResolver,依賴於 Servlet 3.0 對 multipart 的支援

兩者之間,StandardServletMultipartResolver 是優選。將解析器宣告為 bean 即可啟用;
image.png

此外還必須指定相關的配置,這些配置需要在 web.xml 或 Java 配置類中進行指定,需要將 multipart 的細節作為 DispatcherServlet 配置的一部分。
image.png

處理 multipart 資料

最常見的方式是在某個控制器方法引數中使用 @RequestPart 註解接收,可通過以下的方式配置該引數:
1. @RequestPart(“file”) byte[] file
2. @RequestPart(“file”) MultipartFile file (org.springframework.web.multipart.MultipartFile

)
3. @RequestPart(“file”) Part file (javax.servlet.http.Part),此時無需配置 MultipartResolver bean。

異常處理

Spring 提供了多種方式將異常轉換為響應:
1. 特定的 Spring 異常會被自動對映為指定的 HTTP 狀態
2. 異常上可以新增 @ResponseStatus 註解

image.png

  1. 在方法上提交 @ExceptionHandler 註解,使用方法來處理當前控制器中的異常
  2. 控制器新增通常,統一處理全域性的異常
    image.png

跨重定向請求傳遞資料

通過 return "redirect: /spittle/{username}?id=12" 的方式可將請求進行重定向,而 Servlet 體系中請求重定向時原始的請求就結束了,會發起一個新的 GET 請求,原始請求中的模型資料也就消亡了。

  1. 通過 URL 模板將資料放在 url 中進行傳遞,
...
model.addAttribute("username","Tom"); // 放在路徑引數中
model.addAttribute("age",23); // 放在查詢引數中
return "redirect:/spittle/{username}";

上面的程式碼最終得到的 url:/spittle/Tom?age=23
這是一種很簡單直接的方式,缺點也很明顯,不能傳遞複雜物件。

  1. 使用 flash 屬性

原理:在重定向發生之前,將資料放在會話中,在重定向完成之後,從會話中將其取出,並將會話中的資料清理掉。而 Spring 的實現略有不同,需要使用 RedirectAttributes 物件,會話中 flash 屬性會一直攜帶這些資料,直到下一次請求,然後才會消失。
image.png

在重定向執行前,所有通過 RedirectAttributes#addFlashAttribute 新增的屬性會複製到會話中。在重定向後,存在會話中的 flash 屬性會被取出,並從會話轉移到模型中。處理重定向的方法就能從模型中訪問 Spittle 物件了。