SpringBoot接口 - 统一异常处理

super_龙·2022-06-10 10:35·194 次阅读

SpringBoot接口 - 统一异常处理

为什么要统一异常处理#

如果不统一处理异常,程序开发时就需要在controller层写大量重复的Valid代码, 比如下面这个样子:

Copy
@Slf4j @RestController public class Controller { /** * * @param ListReq * @return * @throws Exception */ @RequestMapping("/list") public ResponseMessage getList(@Valid @RequestBody ListReq listReq, BindingResult bindingResult) throws Exception { log.info("start /list,请求参数:{}", JSONObject.toJSONString(listReq)); //参数校验 if (bindingResult.hasErrors()) { bindingResult.getAllErrors().forEach(objectError -> log.warn("[{}]绑定校验错误[{}]", objectError.getCodes()[0], objectError.getDefaultMessage())); return ResponseUtil.setFailedResponse(ResponseStatus.PARAM_FAILED); } // 参数预处理 try { // do something } catch(Exception e) { return ResponseUtil.setFailedResponse(ResponseStatus.PARAM_FAILED); } return ResponseUtil.setSuccessResponse(ResponseStatus.SUCCESS); }

如上所示,每个接口都会进行重复的参数校验、预处理,最终项目中充斥大量的重复代码,臃肿;那么接下来我们学习使用java提供的@ControllerAdvice统一异常处理简化我们的代码。

@ControllerAdvice异常统一处理#

先看代码实现:

异常处理#

Copy
/** * 统一处理异常信息 */ @Slf4j @RestControllerAdvice public class ExceptionAdvice { /** * 捕获接口请求参数校验异常 */ @ResponseBody @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class, MissingServletRequestParameterException.class}) public ResponseMessage handleParameterVerificationException(@NonNull Exception e) { if (e instanceof MethodArgumentNotValidException) { //MethodArgumentNotValidException异常:@RequestBody上validate失败后抛出的异常,json格式有效 BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult(); bindingResult.getAllErrors().forEach( objectError -> log.warn("[{}]绑定校验错误[{}]", objectError.getCodes()[0], objectError.getDefaultMessage())); } else if (e instanceof BindException) { //BindException异常:@RequestBody上validate失败后抛出的异常,表单提交有效 BindingResult bindingResult = ((BindException) e).getBindingResult(); bindingResult.getAllErrors().forEach( objectError -> log.warn("[{}]绑定校验错误[{}]", objectError.getCodes()[0], objectError.getDefaultMessage())); } else { //@RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException异常 //@RequestParam上参数缺失抛出MissingServletRequestParameterException异常 log.warn("绑定校验错误[{}] ", e.getMessage()); } return ResponseUtil.setFailedResponse(ResponseStatus.PARAM_FAILED); } /** * 捕获其他Exception */ @ResponseBody @ExceptionHandler({Exception.class}) public ResponseMessage customExceptionHandler(Exception e) { log.error(e.getMessage()); return ResponseUtil.setFailedResponse(ResponseStatus.FAILED); } }

接口层(无需特殊处理)#

Copy
@Slf4j @Validated @RestController public class Controller { /** * @param listReq * @return * @throws Exception */ @RequestMapping("/list") public ResponseMessage getList(@Valid @RequestBody ListReq listReq) throws Exception { log.info("start /list,请求参数:{}", JSONObject.toJSONString(listReq)); return confMgmtService.getConfList(confListReq); }

以上就是统一处理的简单实现~ 快GET起来吧

posted @   super_龙  阅读(194)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示
目录