这里解决之前留下来的问题,当程序没有失常返回时候
就是程序因为运行时异样导致的后果,有些异样咱们可,能无奈提前预知,不能失常走到咱们return的R对象返回。这个时候该如何解决
在SpringBoot中,能够应用@ControllerAdvice
注解来启用全局异样解决。通过应用@ControllerAdvice注解,能够捕捉应用程序中的所有异样,从而实现对立的异样解决。如果要自定义异样解决办法,能够应用@ExceptionHandler
注解,并指定要捕捉的异样类型。这样就能够对指定的异样进行对立的解决。因而,通过@ControllerAdvice和@ExceptionHandler注解的组合,能够实现全局的异样解决。
代码示列
package cn.soboys.springbootrestfulapi.common.exception;import cn.soboys.springbootrestfulapi.common.resp.R;import cn.soboys.springbootrestfulapi.common.resp.ResultCodeEnum;import org.springframework.context.support.DefaultMessageSourceResolvable;import org.springframework.validation.BindException;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestControllerAdvice;import javax.validation.ConstraintViolation;import javax.validation.ConstraintViolationException;import java.util.stream.Collectors;/** * @author 公众号 程序员三时 * @version 1.0 * @date 2023/4/29 00:21 * @webSite https://github.com/coder-amiao * 对立异样处理器 */@RestControllerAdvicepublic class GlobalExceptionHandler { /** * 通用异样解决办法 **/ @ExceptionHandler(Exception.class) @ResponseBody public R error(Exception e) { e.printStackTrace(); return R.setResult(ResultCodeEnum.INTERNAL_SERVER_ERROR); } /** * 指定异样解决办法 **/ @ExceptionHandler(NullPointerException.class) @ResponseBody public R error(NullPointerException e) { e.printStackTrace(); return R.setResult(ResultCodeEnum.NULL_POINT); } /** * 解决Get申请中 应用@Valid 验证门路中申请实体校验失败后抛出的异样 */ @ExceptionHandler(BindException.class) @ResponseBody public R BindExceptionHandler(BindException e) { String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining()); return R.failure().code(ResultCodeEnum.PARAM_ERROR.getCode()).message(message); } /** * 解决Get申请中 应用@Validated 验证门路中 单个参数申请失败抛出异样 * @param e * @return */ @ExceptionHandler(ConstraintViolationException.class) public R ConstraintViolationExceptionHandler(ConstraintViolationException e) { String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining()); return R.failure().code(ResultCodeEnum.PARAM_ERROR.getCode()).message(message); } /** * 自定义异样解决办法 * * @param e * @return */ @ExceptionHandler(BusinessException.class) @ResponseBody public R error(BusinessException e) { e.printStackTrace(); return R.failure().message(e.getMessage()).code(e.getCode()); }}
异样解决,可能缩小代码的反复度和复杂度,有利于代码的保护,并且可能疾速定位到BUG,大大提高咱们的开发效率。
通过@ControllerAdvice
返回对应谬误视图页面,@RestControllerAdvice
返回json 格局的谬误api,也能够通过@ControllerAdvice
在办法上加上@ResponseBody
返回对应json格局, 类比,controller中返回是一样的
这样临时解决了,咱们上一片文章留下问题
思考
其实这样写,还是不够完满,咱们晓得咱们谬误类型有很多种,参数谬误也有很多,参数校验还没有达到框架级别,
例如这个是阿里云ECS谬误
{ "RequestId": "5E571499-13C5-55E3-9EA6-DEFA0DBC85E4", "HostId": "ecs-cn-hangzhou.aliyuncs.com", "Code": "InvalidOperation.NotSupportedEndpoint", "Message": "The specified endpoint can't operate this region. Please use API DescribeRegions to get the appropriate endpoint, or upgrade your SDK to latest version.", "Recommend": "https://next.api.aliyun.com/troubleshoot?q=InvalidOperation.NotSupportedEndpoint&product=Ecs"}
这是新浪api的
{ "request": "/statuses/home_timeline.json", "error_code": "20502", "error": "Need you follow uid."}
或者说这样
{ "result": false, "error": {"code": 102, "message": "Validation failed: Wrong NAME."}}
咱们如何在进一步改良呢,
下一篇文章会持续分享,留下你的思考
筹备从零做一套本人的开发脚手架模板 ,关注公众 程序员三时