您好,登錄后才能下訂單哦!
spring boot 與mvc的原理一直,所以存在view層的Resolver,可以進行配置和重寫
那么問題來了:
從寫之后的視圖渲染器,如何對視圖頁面不存在的情況進行處理呢
首先,對于spring mvc的機制,404,以及500或是一些異常的處理,主要集中在controller的處理邏輯中
而視圖渲染,如下例:
重寫了ViewResolver,如果這個過程中發生異常,或是反回了一個空的view,環境如何處理,如何調到異常頁面
public class MultiViewResover extends InternalResourceViewResolver { private static List<ViewResolver> resolvers = new ArrayList<>(); @Override public View resolveViewName(String viewName, Locale locale) throws Exception { View view = null; for (ViewResolver resolver : resolvers) { view = resolver.resolveViewName(viewName, locale); if(view != null) { break; } } // if(view == null) { // MustacheView mustacheView = new MustacheView(); // mustacheView.setUrl("pages/error"); // view = mustacheView; // } return view; }
查了下源碼:
也就是說,如果視圖是空的時候,這里會拋出ServletException
/** * Render the given ModelAndView. * <p>This is the last stage in handling a request. It may involve resolving the view by name. * @param mv the ModelAndView to render * @param request current HTTP servlet request * @param response current HTTP servlet response * @throws ServletException if view is missing or cannot be resolved * @throws Exception if there's a problem rendering the view */ protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception { // Determine locale for request and apply it to the response. Locale locale = this.localeResolver.resolveLocale(request); response.setLocale(locale); View view; if (mv.isReference()) { // We need to resolve the view name. view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request); if (view == null) { throw new ServletException("Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" + getServletName() + "'"); } } else { // No need to lookup: the ModelAndView object contains the actual View object. view = mv.getView(); if (view == null) { throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " + "View object in servlet with name '" + getServletName() + "'"); } } // Delegate to the View object for rendering. if (logger.isDebugEnabled()) { logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'"); } try { if (mv.getStatus() != null) { response.setStatus(mv.getStatus().value()); } view.render(mv.getModelInternal(), request, response); } catch (Exception ex) { if (logger.isDebugEnabled()) { logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'", ex); } throw ex; } }
而doDispatch中對所有的異常進行了捕獲:
按照這里描述,可以在interceptor的afterCompletion中進行異常的處理
catch (Throwable err) { // As of 4.3, we're processing Errors thrown from handler methods as well, // making them available for @ExceptionHandler methods and other scenarios. dispatchException = new NestedServletException("Handler dispatch failed", err); } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); }
但interceptor的afterCompletion是在視圖處理完成或發生異常之后的再處理工作
所以可以返回一些靜態頁面,但如果需要使用一些模板引擎,就需要進行繁瑣的處理了
綜上所述,針對于視圖層異常的處理,只能有一下兩種方法了:
1.跳轉到一個固定的異常請求,之后進行再次渲染,這里就需要控制好自己實現的viewResolver了,需要針對于異常界面進行特殊處理
2.springboot 提供的ErrorController機制
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。