Spring 5.2.2 MVC(3)

     接着Spring 5.2.2 MVC (2)基於DispatcherServlet 的內容繼續講。java


異常狀況
web

     若是在請求映射期間發生異常或請求處理程序(如@Controller)引起異常,DispatcherServlet將委託給HandlerExceptionResolver bean   chain(鏈) 以解決異常並提供替代處理,這種典型的錯誤響應。typescript

下表列出了可用的HandlerExceptionResolver 實現:瀏覽器


   1)chain(鏈) 解析器
微信

    經過在Spring配置中聲明多個HandlerExceptionResolver bean並根據須要設置它們的order 屬性,能夠造成異常解析器鏈。order 屬性越大,異常解決程序的位置就越晚。app

HandlerExceptionResolver 指定它能夠返回:ui

  • 指向錯誤視圖的ModelAndView spa

  • 若是異常是在解析器中處理的,則爲空的ModelAndView .net

  • 若是異常仍然未解決,則爲空,以便後續的解析器嘗試,若是異常仍然保留在最後,則容許冒泡上升到Servlet容器。3d

MVC配置會自動聲明爲默認Spring MVC異常、@ResponseStatus註解的異常以及@ExceptionHandler方法的支持聲明內置的解析器。能夠自定義或替換該列表。

2)容器錯誤頁

    若是任何HandlerExceptionResolver仍然沒法解決異常,那麼該異常將被保留以傳播,或者若是響應狀態設置爲錯誤狀態(即4xx、5xx),則Servlet容器能夠在HTML中呈現默認的錯誤頁。要自定義容器的默認錯誤頁,能夠在web.xml中聲明錯誤頁映射。下面的示例演示瞭如何執行此操做:

<error-page> <location>/error</location></error-page>

在前面的示例中,當出現異常或響應具備錯誤狀態時,Servlet容器在容器內對配置的URL進行錯誤分派(例如/error)。而後由DispatcherServlet進行處理,可能將其映射到@Controller,後者能夠實現返回帶有model 的錯誤視圖名稱或返回JSON響應,以下例所示:

@RestControllerpublic class ErrorController {
@RequestMapping(path = "/error") public Map<String, Object> handle(HttpServletRequest request) { Map<String, Object> map = new HashMap<String, Object>(); map.put("status", request.getAttribute("javax.servlet.error.status_code")); map.put("reason", request.getAttribute("javax.servlet.error.message")); return map; }}

Servlet  API沒有提供在Java中建立錯誤頁映射的方法。可是你能夠同時使用WebApplicationInitializer和最少的web.xml


view解析

    Spring MVC定義了ViewResolver View 接口,這些接口容許你在瀏覽器中渲染模型,而沒必要綁定到特定的視圖技術。ViewResolver 提供視圖名稱和實際視圖之間的映射。View 訪問地址在移交給特定視圖技術以前的數據準備。

下表提供了有關ViewResolver 層次結構的詳細信息(ViewResolver 實現):

1)處理(Handling)

    能夠經過聲明多個解析器bean來連接視圖解析器,若是須要,還能夠經過設置order 屬性來指定順序。記住,order 屬性值越大,視圖解析器在鏈中的位置就越晚。

    ViewResolver 的規範指定它能夠返回null以指明找不到視圖。可是,對於JSP和InternalResourceViewResolver,判斷JSP是否存在的惟一方法是經過RequestDispatcher執行分派。因此必須將InternalResourceViewResolver 配置爲視圖解析器的總順序中的最後一個。

    配置視圖解析和將ViewResolver bean添加到Spring配置同樣簡單。MVC配置爲視圖解析器和添加無邏輯視圖控制器提供了一個專用的配置API,這對於沒有控制器邏輯的HTML模板呈現很是有用。

2)重定向(Redirecting

   視圖名稱中的特殊redirect:前綴容許你執行重定向。UrlBasedViewResolver (及其子類)將此識別爲須要重定向的指令。視圖名稱的其他部分是重定向URL。

     實際效果與控制器返回RedirectView相同,但如今控制器自己能夠根據邏輯視圖名稱進行操做。邏輯視圖名稱(例如redirect:/myapp/some/resource)相對於當前的Servlet上下文重定向,而redirect:https://myhost.com/some/arbitrary/path等名稱重定向到絕對URL。

     注意,若是用@ResponseStatus註解了控制器方法,則註解值優先於RedirectView設置的響應狀態。

3)轉發(Forwarding)

    你還能夠由UrlBasedViewResolver 和子類解析的視圖名稱使用特殊的forward:前綴。這將建立一個InternalResourceView,它執行RequestDispatcher.forward()。所以這個前綴對於InternalResourceViewResolver InternalResourceView (對於JSP)是沒有用的,可是若是你使用另外一種視圖技術,但仍然但願強制資源的轉發由Servlet/JSP引擎處理,那麼它可能會有幫助。請注意,你也能夠連接多個視圖解析器。

4)內容規範(Content Negotiation)

     ContentNegotiatingViewResolver不解析視圖自己,而是將其委託給其餘視圖解析器,並選擇與客戶端請求的表示相似的視圖。能夠經過Accept 頭或查詢參數(例如"/path?format=pdf")。

    ContentNegotiatingViewResolver經過將請求媒體類型與每一個ViewResolver關聯的View 所支持的媒體類型(也稱爲Content-Type)進行比較,選擇適當的View 來處理請求。列表中具備兼容Content-Type的第一個View 表示返回給客戶端。若是ViewResolver鏈沒法提供兼容視圖,則會查找經過DefaultViews 屬性指定的Views 列表。後一個選項適用於能夠呈現當前資源的適當表示的單例視圖,而無論邏輯視圖名稱如何。Accept頭能夠包含通配符(例如text/*),在這種狀況下,Content-Typetext/xml的視圖是兼容的匹配項。


明天把基於DispatcherServlet 的剩餘內容講完。


敬請持續關注。


歡迎關注和轉發Spring中文社區(加微信羣,能夠關注後加我微信):


本文分享自微信公衆號 - Spring中文社區(gh_81d233bb13a4)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索