SpringMVC---异常处理源码学习

一、源码分析

       processDispatchResult(…, (Exception)dispatchException):之前目标方法执行出现的异常也会作为参数传入这个方法

	private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {
	        boolean errorView = false;
	        if (exception != null) {
	            if (exception instanceof ModelAndViewDefiningException) {
	                this.logger.debug("ModelAndViewDefiningException encountered", exception);
	                mv = ((ModelAndViewDefiningException)exception).getModelAndView();
	            } else {
	                Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;
	                mv = this.processHandlerException(request, response, handler, exception);	//处理异常
	                errorView = mv != null;
	            }
	        }
	        ...
	    }
	protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) throws Exception {
	        request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
	        ModelAndView exMv = null;
	        if (this.handlerExceptionResolvers != null) {
	            Iterator var6 = this.handlerExceptionResolvers.iterator();
	
	            while(var6.hasNext()) {
	                HandlerExceptionResolver resolver = (HandlerExceptionResolver)var6.next();
	                exMv = resolver.resolveException(request, response, handler, ex);
	                if (exMv != null) {
	                    break;
	                }
	            }
	        }
	
	        if (exMv != null) {
	            if (exMv.isEmpty()) {
	                request.setAttribute(EXCEPTION_ATTRIBUTE, ex);
	                return null;
	            } else {
	                if (!exMv.hasView()) {
	                    String defaultViewName = this.getDefaultViewName(request);
	                    if (defaultViewName != null) {
	                        exMv.setViewName(defaultViewName);
	                    }
	                }
	
	                if (this.logger.isTraceEnabled()) {
	                    this.logger.trace("Using resolved error view: " + exMv, ex);
	                }
	
	                if (this.logger.isDebugEnabled()) {
	                    this.logger.debug("Using resolved error view: " + exMv);
	                }
	
	                WebUtils.exposeErrorRequestAttributes(request, ex, this.getServletName());
	                return exMv;
	            }
	        } else {
	            throw ex;
	        }
	    }

Alt



二、异常处理实例

1、本类的异常处理(本类的异常处理方法只能处理本类中发生的异常)

       控制器代码:

	@Controller
	public class TestExceptionController {
	
	    @RequestMapping("/ex")
	    public String test() {
	        int i = 10 / 0;
	        return "resp";
	    }
	
	    @ExceptionHandler(value = {ArithmeticException.class})
	    public ModelAndView catex(Exception e) {	//value指定具体的异常类
	        System.out.println(e);
	        ModelAndView modelAndView = new ModelAndView("error");
	        modelAndView.addObject("exception", e);
	        return modelAndView;
	    }
	}

       error.jsp:

	<%@ page contentType="text/html;charset=UTF-8" language="java" %>
	<html>
	<head>
	    <title>Error</title>
	</head>
	<body>
	<h2>出错了!</h2>
	<h2>出错信息: ${exception}</h2>
	</body>
	</html>

       测试结果:
Alt

2、全局异常处理(可以处理所有的异常,多个异常处理方法按照精确优先的原则)

       全局类:

	@ControllerAdvice
	public class GlobalExceptionHandler {
	
	    @ExceptionHandler(value = {ArithmeticException.class})
	    public ModelAndView catex(Exception e) {	//value指定具体的异常类
	        System.out.println(e);
	        ModelAndView modelAndView = new ModelAndView("error");
	        modelAndView.addObject("exception", e);
	        return modelAndView;
	    }
	}

       测试结果:
Alt

发布了33 篇原创文章 · 获赞 5 · 访问量 2280

猜你喜欢

转载自blog.csdn.net/cj1561435010/article/details/104080823