溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

spring boot view override

發(fā)布時間:2020-08-17 12:07:16 來源:網(wǎng)絡(luò) 閱讀:3047 作者:xiaosawuhen 欄目:開發(fā)技術(shù)

spring boot 與mvc的原理一直,所以存在view層的Resolver,可以進行配置和重寫


那么問題來了:

從寫之后的視圖渲染器,如何對視圖頁面不存在的情況進行處理呢


首先,對于spring mvc的機制,404,以及500或是一些異常的處理,主要集中在controller的處理邏輯中


而視圖渲染,如下例: 

重寫了ViewResolver,如果這個過程中發(fā)生異常,或是反回了一個空的view,環(huán)境如何處理,如何調(diào)到異常頁面

	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是在視圖處理完成或發(fā)生異常之后的再處理工作

所以可以返回一些靜態(tài)頁面,但如果需要使用一些模板引擎,就需要進行繁瑣的處理了

綜上所述,針對于視圖層異常的處理,只能有一下兩種方法了:

1.跳轉(zhuǎn)到一個固定的異常請求,之后進行再次渲染,這里就需要控制好自己實現(xiàn)的viewResolver了,需要針對于異常界面進行特殊處理

2.springboot 提供的ErrorController機制




向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI