博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring mvc异常处理设置
阅读量:5768 次
发布时间:2019-06-18

本文共 5648 字,大约阅读时间需要 18 分钟。

hot3.png

最近使用spring mvc开发一个web系统,发现在controller里发生未捕获异常时不出日志。

分析DispatcherServlet,初始化handlerExceptionResolvers

/**	 * Initialize the strategy objects that this servlet uses.	 * 

May be overridden in subclasses in order to initialize * further strategy objects. */ protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context);// 初始化异常处理支持器 initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); }// 进入初始化处理方法,具体内容就不贴了,主要是先到上下文中搜寻我们自己定义的ExceptionResolvers,如果没有自定义的resolvers,从默认配置中读取。private void initHandlerExceptionResolvers(ApplicationContext context)// 从默认策略中取得默认配置,从DispatcherServlet.properties文件中取得相关的配置策略,但是在spring2.5的mvc jar包中properties文件中没有HandlerExceptionResolver的默认配置,返回一个EmptyList给handlerExceptionResolversprotected List getDefaultStrategies(ApplicationContext context, Class strategyInterface)

 

分析DispatcherServlet,分发处理请求

 

 

// 从dispatch方法中看到,系统对请求进行具体的逻辑处理部分被catch住了一次exception,然后会使用servlet持有的ExceptionResolver进行处理protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {		HttpServletRequest processedRequest = request;		HandlerExecutionChain mappedHandler = null;		int interceptorIndex = -1;		// Expose current LocaleResolver and request as LocaleContext.		LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();		LocaleContextHolder.setLocaleContext(buildLocaleContext(request), this.threadContextInheritable);		// Expose current RequestAttributes to current thread.		RequestAttributes previousRequestAttributes = RequestContextHolder.getRequestAttributes();		ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);		RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);		if (logger.isTraceEnabled()) {			logger.trace("Bound request context to thread: " + request);		}				try {			ModelAndView mv = null;			boolean errorView = false;			try {				processedRequest = checkMultipart(request);				// Determine handler for the current request.				mappedHandler = getHandler(processedRequest, false);				if (mappedHandler == null || mappedHandler.getHandler() == null) {					noHandlerFound(processedRequest, response);					return;				}				// Apply preHandle methods of registered interceptors.				HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();				if (interceptors != null) {					for (int i = 0; i < interceptors.length; i++) {						HandlerInterceptor interceptor = interceptors[i];						if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {							triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);							return;						}						interceptorIndex = i;					}				}				// Actually invoke the handler.				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());				// Do we need view name translation?				if (mv != null && !mv.hasView()) {					mv.setViewName(getDefaultViewName(request));				}				// Apply postHandle methods of registered interceptors.				if (interceptors != null) {					for (int i = interceptors.length - 1; i >= 0; i--) {						HandlerInterceptor interceptor = interceptors[i];						interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);					}				}			}			catch (ModelAndViewDefiningException ex) {				logger.debug("ModelAndViewDefiningException encountered", ex);				mv = ex.getModelAndView();			}// 这里catch住controller抛出的异常,使用持有的ExceptionResolver处理,当没有配置自己的处理器时,程序会将异常继续往上抛出,最终交给我们的容器处理			catch (Exception ex) {				Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);				mv = processHandlerException(processedRequest, response, handler, ex);				errorView = (mv != null);			}			// Did the handler return a view to render?			if (mv != null && !mv.wasCleared()) {				render(mv, processedRequest, response);				if (errorView) {					WebUtils.clearErrorRequestAttributes(request);				}			}			else {				if (logger.isDebugEnabled()) {					logger.debug("Null ModelAndView returned to DispatcherServlet with name '" +							getServletName() + "': assuming HandlerAdapter completed request handling");				}			}			// Trigger after-completion for successful outcome.			triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);		}// 当没有配置ExceptionResolver时,异常将到达这里,最终抛出		catch (Exception ex) {			// Trigger after-completion for thrown exception.			triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);			throw ex;		}		catch (Error err) {			ServletException ex = new NestedServletException("Handler processing failed", err);			// Trigger after-completion for thrown exception.			triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);			throw ex;		}		finally {			// Clean up any resources used by a multipart request.			if (processedRequest != request) {				cleanupMultipart(processedRequest);			}			// Reset thread-bound context.			RequestContextHolder.setRequestAttributes(previousRequestAttributes, this.threadContextInheritable);			LocaleContextHolder.setLocaleContext(previousLocaleContext, this.threadContextInheritable);			// Clear request attributes.			requestAttributes.requestCompleted();			if (logger.isTraceEnabled()) {				logger.trace("Cleared thread-bound request context: " + request);			}		}	}

关于异常处理的配置:
spring mvc异常设置

转载于:https://my.oschina.net/dreamnight/blog/695039

你可能感兴趣的文章
2016/08/25 The Secret Assumption of Agile
查看>>
(Portal 开发读书笔记)Portlet间交互-PortletSession
查看>>
搭建vsftpd服务器,使用匿名账户登入
查看>>
AMD改善Linux驱动,支持动态电源管理
查看>>
JAVA中循环删除list中元素的方法总结
查看>>
Java虚拟机管理的内存运行时数据区域解释
查看>>
人人都会深度学习之Tensorflow基础快速入门
查看>>
ChPlayer播放器的使用
查看>>
js 经过修改改良的全浏览器支持的软键盘,随机排列
查看>>
Mysql读写分离
查看>>
Oracle 备份与恢复学习笔记(5_1)
查看>>
Oracle 备份与恢复学习笔记(14)
查看>>
分布式配置中心disconf第一部(基本介绍)
查看>>
Scenario 9-Shared Uplink Set with Active/Active uplink,802.3ad(LACP)-Flex-10
查看>>
UML类图中的六种关系
查看>>
探寻Interpolator源码,自定义插值器
查看>>
一致性哈希
查看>>
mysql(待整理)
查看>>
看雪论坛502,出现安全宝?
查看>>
使用PullToRefresh实现下拉刷新和上拉加载
查看>>