浏览 7738 次
锁定老帖子 主题:spring mvc异常处理设置
精华帖 (4) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (2)
|
|
---|---|
作者 | 正文 |
发表时间:2011-12-09
分析DispatcherServlet,初始化handlerExceptionResolvers /** * Initialize the strategy objects that this servlet uses. * <p>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给handlerExceptionResolvers protected 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异常设置http://fancyboy2050.iteye.com/blog/965663 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-12-12
感谢楼主提供的配置,正好项目需要
|
|
返回顶楼 | |
发表时间:2011-12-12
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="defaultErrorView"> <value>system/exception</value> </property> <property name="exceptionMappings"> <props> <prop key="org.springframework.dao.DataAccessException">common/error</prop> <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">common/error</prop> </props> </property> </bean> |
|
返回顶楼 | |
发表时间:2011-12-13
counters15 写道 感谢楼主提供的配置,正好项目需要
互相帮助嘛! 这个地方确实,不做显示的配置不输出日志,会比较困惑。 我这边开发了一个走hessian协议的专门提供远程服务的工程,所以在web文件里也没有添加错误页面,错误不输出日志就把我迷惑了。 |
|
返回顶楼 | |
发表时间:2012-05-17
各位亲们,对render(mv, processedRequest, response);抛出的异常怎么处理呢?总不可能把异常信息直白的显示在页面上吧,对用户体验不好。
为什么不把render(mv, processedRequest, response);放到 try{里面呢? }catch (Exception ex) { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(processedRequest, response, handler, ex); errorView = (mv != null); } |
|
返回顶楼 | |