SpringMVC核心接口
DispatcherServlet
DispatcherServlet有點類似HttpServlet接口中用於轉發的接口RequestDispatcher
下面是API中對DispatcherServlet的解釋
- 它可以使用任何HandlerMapping實現(預先構建或作為應用程序的一部分提供)來控制請求到處理程序對象的路由。默認是BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping。HandlerMapping對象可以在servlet的應用程序上下文中定義為bean,實現HandlerMapping接口,在出現時覆蓋默認的HandlerMapping。HandlerMappings可以提供任何bean名
- 它可以使用任何HandlerAdapter;這允許使用任何處理程序接口。默認適配器分別是HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter,用於Spring的HttpRequestHandler和控制器接口。還將註冊一個默認的AnnotationMethodHandlerAdapter。HandlerAdapter對象可以作為bean添加到應用程序上下文中,覆蓋默認的HandlerAdapter。與HandlerMappings一樣,handleradapter可以提供任何bean名稱
- 可以通過HandlerExceptionResolver
-
它的視圖解析策略可以通過ViewResolver實現指定,將符號視圖名稱解析為視圖對象。默認是InternalResourceViewResolver。可以將ViewResolver對象作為bean添加到應用程序上下文中,覆蓋默認的ViewResolver。可以給ViewResolvers賦予任何bean名稱
下面分別解釋上面三個關鍵接口
HandlerMapping
handlerMapping的初始化完成的最重要的兩個工作就是:
- 將URL與handler對應的關系保存在handlerMap集合中
setUrlMap(Map<String,?> urlMap) Set a Map with URL paths as keys and handler beans (or handler bean names) as values. |
- 前端控制器(DispatcherSerlvet)根據Request中的url去查找Handler, 返回 HandlerExecutionChain對象,而且在這個HandlerExecutionChain對象中將包含用戶自定義的多個HandlerInterceptor
接口中的preHandler和postHandler分別在Handler執行前和執行後執行。類似Servlet規範中的Fliter,大家可以參考這個設計模式
getHandler(HttpServletRequest request) Return a handler and any interceptors for this request. |
工作中常用RequestMappingHandlerMapping去查找Handler(通過Handler的適配器去查找)
HandlerAdapter
- HandlerMapping可以完成URL和Handler的對應關系。HandlerAdapter可以幫助定義各種Handler。可以參考適配器的設計模式
HandlerAdapter初始化會將這個HandlerAdapter對象保存在Dispatcher的HandlerAdapters集合中。當SpringMVC將某個URL對應到某個Handler時,將對應的Handler返回,對應HandlerAdaptor接口的handle方法
SpringMVC HandlerAdapter機制可以讓Handler的實現更加靈活
handle(HttpServletRequest request, HttpServletResponse response, Object handler) Use the given handler to handle this request. |
工作中常用的RequestMappingHandlerAdapter此適配器能執行實現Controller接口的handler
HandlerExceptionResolver 處理器異常解析
當後臺捕捉到的業務異常時,可以自定義的異常,然後通過實現HandlerExceptionResolver來拋出自定義異常的信息
- 自定義一個異常
-
public class CustomException extends Exception{ public String msg; public CustomException(String msg) { super(msg); this.msg=msg; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
以JSON的格式拋出去
public class CustomExceptionResolver implements HandlerExceptionResolver{ @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) { //handler 就是處理器適配器執行的Handler對象 response.setContentType("application/json;charset=UTF-8"); try { PrintWriter writer = response.getWriter(); Map<String, Object> map = new HashMap<String, Object>(); map.put("success", false); // 為安全起見,只有業務異常我們對前端可見,否則統一歸為系統異常 if (exception instanceof CustomException) { map.put("errorMsg", exception.getMessage()); } else { map.put("errorMsg", "系統異常!"); } writer.write(JSON.toJSONString(map)); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } return null; } }
在這裏,我們不想讓錯誤跳轉到一個錯誤頁面,所以 return null。(以JSON的數據格式 通過response write到前端)接到錯誤信息想怎麽去做,前端自行處理。
- ViewResolver 視圖解析器 將把邏輯視圖名解析為具體的View
應用程序中,我們的頁面經常統一放在某個包下(/WEB-INF/page/),而且統一以某個名字結尾(.jsp或者.html),會統 實現類UrlBasedViewResolver:其中有兩個方法
setSuffix 設置在構建URL時附加到視圖名稱的後綴。
setPreffix 在構建URL時,設置前綴以查看名稱。
通過這兩個方法,我們在return一個字符串時,可以把頁面的前綴和後綴省略,簡化了編碼。
SpringMVC核心接口