为什么要优雅的处理异常
如果我们不统一的处理异常,经常会在controller层有大量的异常处理的代码, 比如:
@Slf4j@Api(value = "User Interfaces", tags = "User Interfaces")@RestController@RequestMapping("/user")public class UserController { /** * http://localhost:8080/user/add . * * @param userParam user param * @return user */ @ApiOperation("Add User") @ApiImplicitParam(name = "userParam", type = "body", dataTypeClass = UserParam.class, required = true) @PostMapping("add") public ResponseEntity<String> add(@Valid @RequestBody UserParam userParam) { // 每个接口充斥着大量的异常处理 try { // do something } catch(Exception e) { return ResponseEntity.fail("error"); } return ResponseEntity.ok("success"); }}
那怎么实现统一的异常处理,特别是结合参数校验等封装?
实现案例
简单展示通过@ControllerAdvice进行统一异常处理。
@ControllerAdvice异常统一处理
对于400参数错误异常
/** * Global exception handler. * * @author pdai */@Slf4j@RestControllerAdvicepublic class GlobalExceptionHandler { /** * exception handler for bad request. * * @param e * exception * @return ResponseResult */ @ResponseBody @ResponseStatus(code = HttpStatus.BAD_REQUEST) @ExceptionHandler(value = { BindException.class, ValidationException.class, MethodArgumentNotValidException.class }) public ResponseResult<ExceptionData> handleParameterVerificationException(@NonNull Exception e) { ExceptionData.ExceptionDataBuilder exceptionDataBuilder = ExceptionData.builder(); log.warn("Exception: {}", e.getMessage()); if (e instanceof BindException) { BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult(); bindingResult.getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage) .forEach(exceptionDataBuilder::error); } else if (e instanceof ConstraintViolationException) { if (e.getMessage() != null) { exceptionDataBuilder.error(e.getMessage()); } } else { exceptionDataBuilder.error("invalid parameter"); } return ResponseResultEntity.fail(exceptionDataBuilder.build(), "invalid parameter"); }}
对于自定义异常
/** * handle business exception. * * @param businessException * business exception * @return ResponseResult */@ResponseBody@ExceptionHandler(BusinessException.class)public ResponseResult<BusinessException> processBusiness