为什么要优雅的处理异常
实现案例@ControllerAdvice异常统一处理Controller接口运行测试
进一步理解@ControllerAdvice还可以怎么用?@ControllerAdvice是如何起作用的(原理)?
示例源码
更多内容
SpringBoot接口如何对异常进行统一封装,并统一返回呢?以上文的参数校验为例,如何优雅的将参数校验的错误信息统一处理并封装返回呢?@pdai
为什么要优雅的处理异常
如果我们不统一的处理异常,经常会在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
add(@Valid @RequestBody UserParam userParam) { - // 每个接口充斥着大量的异常处理
- try {
- // do something
- } catch(Exception e) {
- return ResponseEntity.fail("error");
- }
- return ResponseEntity.ok("success");
- }
- }
那怎么实现统一的异常处理,特别是结合参数校验等封装?
简单展示通过@ControllerAdvice进行统一异常处理。
对于400参数错误异常
- /**
- * Global exception handler.
- *
- * @author pdai
- */
- @Slf4j
- @RestControllerAdvice
- public 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(BusinessExc