日常后端业务开发中,在提供接口服务时会遇到各种异常处理,通常涉及到参数校验异常、自定义异常以及一些不可预知的异常等等。下面就来说一下在springboot中如何在接口层进行全局性的异常处理。
全局异常处理
全局异常处理借用springmvc中的@ControllerAdvice注解来实现,当然在springboot中我们就用@RestControllerAdvice(内部包含@ControllerAdvice和@ResponseBody的特性)。此注解用来监听controller层抛出的异常,以至于让我们能进一步对异常做处理。
下面给出一个全局异常处理案例代码,涉及的有validaton注解校验的异常处理,自定义异常的处理,未知异常的处理。
注意:异常的handler域是由小至大的,所以有先后顺序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| package com.lazycece.sbac.exception.controller;
import com.lazycece.sbac.exception.exception.AbstractGlobalException; import com.lazycece.sbac.exception.response.ResCode; import com.lazycece.sbac.exception.response.ResMsg; import com.lazycece.sbac.exception.response.ResponseData; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.BindException; import org.springframework.validation.BindingResult; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.ServletException;
@RestControllerAdvice @Slf4j public class GlobalExceptionHandler {
@ExceptionHandler(value = {BindException.class, MethodArgumentNotValidException.class}) public ResponseData bindExceptionHandler(Exception e) { BindingResult bindingResult; if (e instanceof BindException) { bindingResult = ((BindException) e).getBindingResult(); } else { bindingResult = ((MethodArgumentNotValidException) e).getBindingResult(); } StringBuilder stringBuilder = new StringBuilder(); bindingResult.getAllErrors().forEach( objectError -> stringBuilder.append(",").append(objectError.getDefaultMessage()) ); String errorMessage = stringBuilder.toString(); errorMessage = errorMessage.substring(1, errorMessage.length()); return ResponseData.builder().code(ResCode.FAIL).message(errorMessage).build(); }
@ExceptionHandler(value = AbstractGlobalException.class) public ResponseData customExceptionHandler(AbstractGlobalException e) { return ResponseData.builder().code(e.getCode()).message(e.getMessage()).build(); }
@ExceptionHandler(value = Exception.class) public ResponseData commonExceptionHandler(Exception e) throws ServletException { if (e instanceof ServletException) { throw (ServletException) e; } log.error("server inner error: {}", e); return ResponseData.builder().code(ResCode.FAIL).message(ResMsg.SERVER_INNER_ERROR).build(); } }
|
案例源码
案例源码地址:https://github.com/lazycece/springboot-actual-combat/tree/master/springboot-ac-exception