pringBoot统一异常处理

在项目的开发和调试中,错误难免发生。在java中这种程序错误就叫做异常,如果程序出现异常,会是什么样子呢。看下图

SpringBoot入门-统一异常处理

这种异常展现方式有很多问题,首先对用户很不友好,而且里面包含了栈信息,造成安全隐患,同时对于前端小伙伴对接也会造成不便。

通用异常处理

java中所有异常的基类是Exception类,处理好这个类就能处理所有异常了

SpringBoot为我们提供了@ControllerAdvice注解来处理异常

@ControllerAdvice
public class ExceptionControllerAdvice extends BaseController {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Result exceptionHandler(Exception ex) {
        logger.error("服务器异常: {}", ex);
        return resultFail("服务器出错了,请稍后再试");
    }

@ExceptionHandler注解用来标识这个方法处理的异常,我们只需要把异常的详细信息写入日志系统,返回用户简单的错误提示就行了,错误码是0,这样也方便前端小伙伴做统一的错误提示

SpringBoot入门-统一异常处理
SpringBoot入门-统一异常处理

业务异常处理

先看一个简单的需求,登录功能。登录成功返回token,失败返回账号错误的提示信息。看看service层的实现

public String login(String name, String password) {
    if ("cloud".equals(name) && "123".equals(password)) {
        String token = "token";
        return token;
    } else {
        return "";
    }
}
SpringBoot入门-统一异常处理

登录成功返回token,失败返回空字符串。controller层通过判断login方法的返回值是否为空来决定是返回token还是返回错误信息。

 @GetMapping("/login")
public Result login(String name, String password) {
    String token = userService.login(name, password);
    if (StringUtils.isEmpty(token)) {
        return resultFail("账户错误");
    } else {
        return resultOk(token);
    }
}
SpringBoot入门-统一异常处理

但这种实现方式有很多不好的地方,首先是正常流程和异常流程没有分离,其实调用者只关心正常流程,其次这种方式没法让事务回退,比如我在登陆方法里记录了一些信息,但登陆失败后这些信息是不需要的,需要回退。如何解决呢?我们可以通过引入业务异常类来解决。

public class ServiceFailException extends RuntimeException
SpringBoot入门-统一异常处理

新建一个异常类,继承自RuntimeException,这样就不需要强制用try catch捕获异常

改写login方法

public String login(String name, String password) {
    if ("cloud".equals(name) && "123".equals(password)) {
        String token = "token";
        return token;
    }
    throw new ServiceFailException("账号错误");
}
SpringBoot入门-统一异常处理

改写controller方法

@GetMapping("/login")
public Result login(String name, String password) {
    return resultOk(userService.login(name, password));
}

可以看到调用方只需要考虑正常流程,变的异常简洁

在ControllerExceptionAdvice类下面处理该自定义异常

@ResponseBody
@ExceptionHandler(value = ServiceFailException.class)
public Result serviceFailHandler(ServiceFailException ex) {
    logger.error("service层异常: {}", ex);
    return resultFail(ex.getStatus(), ex.getMessage());
}
public Result serviceFailHandler(ServiceFailException ex) {

错误信息展示

参考项目(模块: SpringBoot-HelloWorld):
https://gitee.com/huatin/java-test

内容出处:,

声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/procedure/26768.html

发表评论

登录后才能评论