spring mvc中的异常处理

  • 1、在/error下的4xx.html 或者5xx.html 会被自动解析,所以自定义错误页放在该目录下就可以被解析到。

To map all 5xx errors by using a FreeMarker template, your directory structure would be as follows:
src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.ftlh
             +- <other templates>

在找不到精确的比如400.html 错误后会寻找4xx.html错误

DefaultErrorViewResolver.java 
	@Override
	public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
		ModelAndView modelAndView = resolve(String.valueOf(status.value()), model);
		if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
			modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
		}
		return modelAndView;
	}
	@Override
	public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
		ModelAndView modelAndView = resolve(String.valueOf(status.value()), model);
		if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
			modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
		}
		return modelAndView;
	}

	private ModelAndView resolve(String viewName, Map<String, Object> model) {
		String errorViewName = "error/" + viewName;
		TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName,
				this.applicationContext);
		if (provider != null) {
			return new ModelAndView(errorViewName, model);
		}
		return resolveResource(errorViewName, model);
	}

	private ModelAndView resolveResource(String viewName, Map<String, Object> model) {
		for (String location : this.resources.getStaticLocations()) {
			try {
				Resource resource = this.applicationContext.getResource(location);
				resource = resource.createRelative(viewName + ".html");
				if (resource.exists()) {
					return new ModelAndView(new HtmlResourceView(resource), model);
				}
			}
			catch (Exception ex) {
			}
		}
		return null;
	}

  • 2、自定义异常类并且使用@Responsestatus结合方式1即可自定义展示信息。

@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR,reason = "zero by gaojl 000!!!!!!!!!")
public class ZeroDividException extends RuntimeException {
    public  ZeroDividException(String message){
        super(message);
    }
}

这样当dispatcher 调度时候,

mv = ha.handle(processedRequest,response,mappedHandler.getHandler());

捕获到我们抛出的异常时候,就会调用异常处理器处理抛出的自定义异常。最后会发起“/error”请求BasicErrorController中的


	@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
	public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
		HttpStatus status = getStatus(request);
		Map<String, Object> model = Collections
				.unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
		response.setStatus(status.value());
		ModelAndView modelAndView = resolveErrorView(request, response, status, model);
		return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
	}

返回ModeAndView,从而可以返回模板下、/error/500.html 的页面,由于在第一种方式中解释了DefaultErrorViewResolver 可以在不能精确匹配的情况下使用5xx.html代替响应。
所以我觉得原理可以总结如下:当我们自定义异常类使用@Responsestatus(value=Httpstatuscode,reason="")注解标注时,调用handlerExceptionResolver(ResponseStatusExceptionResolver)解析,同时在请求域request中加入异常信息同时返回null模型视图对象,tomcat底层调用sendError 从而再次发起/error请求,BasicErrorController 创建ModeAndView 返回ModeAndView,然后进行处理得到View 渲染写给浏览器。

  • 3、第三种也是最普遍的一种 使用@ControllerAdvice 和@ExceptionHandler({xxxException.class})

一般用来处理全局异常。

@Slf4j
@ControllerAdvice
public class MyException {
    @ExceptionHandler({ArithmeticException.class})
    public String zeroException(Exception ex){
        return "success";
    }
}

这样当HandlerExceptionResolver 解析时 得到ModeAndView 从而得到View 进而渲染到success页面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值