浅谈Spring Boot 异常处理篇

 更新时间:2017年08月29日 09:03:23   作者:Anoyi  
本篇文章主要介绍了浅谈Spring Boot 异常处理篇,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

前言

先谈谈“异常处理”这件事。下面有 2 份伪代码,对比下:

// ① 基于 if/else 判断
if(deletePage(page) == E_OK){
 if(registry.deleteReference(page.name) == E_OK){
  if(configKeys.deleteKey(page.name.makeKey()) == E_OK){
   logger.log("page deleted");
  }else{
   logger.log("configKey not deleted");
  }
 }else{
  logger.log("deleteReference from registry failed");
 }
}else{
 logger.log("delete failed");
 return E_RROR;
}
// ② 基于异常处理
try{
 deletePage(page);
 registry.deleteReference(page.name);
 configKeys.deleteKey(page.name.makeKey());
}catch(Exception e){
 logError(e);
}

可以看出,如果使用异常替代返回错误码,错误处理代码就能从主路径逻辑中分离出来,得到简化!

②中,基于异常处理的代码真的好吗?其实是丑陋不堪的,它搞乱了代码结构,把错误处理与正常流程混为一谈。最好把 try 和 catch 代码块的主体部分抽离出来,形成另外的函数。

// ③ 优雅的异常处理逻辑
public void delete(Page page){
 try{
  deletePageAndAllReferences(page);
 }catch(Exception e){
  logError(e);
 }
}

private void deletePageAndAllReferences(Page page) throw Exception{
 deletePage(page);
 registry.deleteReference(page.name);
 configKeys.deleteKey(page.name.makeKey());
}

private void logError(Exception e){
 logger.log(e.getMessage());
}

③中,函数各司其职,更易于理解和修改了。

总结:使用异常而不是错误码,优雅地使用异常!函数应该只做一件事,处理错误就是一件事。因此,处理错误的函数不该做其他事!

在 Spring Boot 中处理异常

1、默认的异常处理

例如 401,404,500,5XX 等异常,Spring Boot 默认会跳转到预配置的页面,此处以 thymeleaf 模板引擎为例:

+ resources
 + templates
  + error
   - 401.html
   - 404.html
   - 500.html

只需在 resources/templates/error/ 路径下添加对应的html文件即可。

2、局部异常处理

局部异常一般处理业务逻辑出现的异常情况,在 Controller 下使用 @ExceptionHandler 注解来处理异常。举个小例子:

先定义 ResponseBean 和 ExceptionEnum 两个对象,辅助完成优雅的代码。

/**
 * 统一响应
 * @author anoy
 */
public class ResponseBean<T> {

  private int code;

  private String message;

  private T data;

  public ResponseBean(){}

  public ResponseBean(ExceptionEnum exceptionEnum){
    this.code = exceptionEnum.getCode();
    this.message = exceptionEnum.getMessage();
  }

  // 省略 setter/getter
}

/**
 * 异常类型枚举
 * @author anoy
 */
public enum ExceptionEnum {

  GIRL_FRIEND_NOT_FOUND(100000, "girl friend not found");

  private int code;

  private String message;

  ExceptionEnum(int code, String message){
    this.code = code;
    this.message = message;
  }

  public int getCode() {
    return code;
  }

  public String getMessage() {
    return message;
  }
}

今天七夕,写个 GirlFriendNotFoundException(很有同感,是不是?)

@Controller
public class UserController {

  @RequestMapping("/friend/{id}")
  public String friend(@PathVariable("id") Long id) throws GirlFriendNotFoundException {
    if (id == 1L){
      throw new GirlFriendNotFoundException();
    }
    return "friend";
  }

  @ExceptionHandler(GirlFriendNotFoundException.class)
  @ResponseBody
  public ResponseBean handleGirlFriendNotFound(GirlFriendNotFoundException exception){
    loggerError(exception);
    return new ResponseBean(ExceptionEnum.GIRL_FRIEND_NOT_FOUND);
  }
  
  private void logError(Exception e){
    logger.error(e.getMessage());
  }
}

3、全局异常处理

个人观点:全局异常应该处理系统故障级别的问题,像参数校验这种类型的异常,应该作为局部异常来处理,例如 Redis 连接断开,无法请求数据,这种异常就应该当做全局异常来处理,在异常处理的逻辑中,还应该添加通知到开发人员的功能,方便开发人员及时处理错误!

全局异常处理,使用 @ControllerAdvice @ExceptionHandler 来配合。

@ControllerAdvice
public class GlobalExceptionHandler {

  @ExceptionHandler(RedisConnectionFailureException.class)
  public void handlerRedisConnectionFailureException(RedisConnectionFailureException exception){
    logError(exception);
    noticeToDev();
  }

  private void logError(Exception e){
    logger.error(e.getMessage());
  }

  private void noticeToDev(){
    // 通知具体开发人员
  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Springboot工具类FileCopyUtils使用教程

    Springboot工具类FileCopyUtils使用教程

    这篇文章主要介绍了Springboot内置的工具类之FileCopyUtils的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • Eclipse智能提示及快捷键

    Eclipse智能提示及快捷键

    本文主要介绍了Eclipse智能提示及快捷键的相关知识,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • Java适配器模式应用之电源适配器功能详解

    Java适配器模式应用之电源适配器功能详解

    这篇文章主要介绍了Java适配器模式应用之电源适配器功能,较为详细的分析了适配器模式的概念、原理及Java基于适配器模式实现电源适配器功能的相关操作技巧与注意事项,需要的朋友可以参考下
    2018-05-05
  • Spring MVC-@RequestMapping注解详解

    Spring MVC-@RequestMapping注解详解

    @RequestMapping注解的作用,就是将请求和处理请求的控制器方法关联起来,建立映射关系。这篇文章主要给大家介绍了关于SpringMVC中@RequestMapping注解用法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-04-04
  • java环境中的JDK、JVM、JRE详细介绍

    java环境中的JDK、JVM、JRE详细介绍

    这篇文章主要介绍了java环境中的JDK、JVM、JRE详细介绍的相关资料,对于初学者还是有必要了解下,细致说明他们是什么,需要的朋友可以参考下
    2016-11-11
  • SpringBoot模拟员工数据库并实现增删改查操作

    SpringBoot模拟员工数据库并实现增删改查操作

    这篇文章主要给大家介绍了关于SpringBoot模拟员工数据库并实现增删改查操作的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-09-09
  • 详解Spring系列之@ComponentScan批量注册bean

    详解Spring系列之@ComponentScan批量注册bean

    本文介绍各种@ComponentScan批量扫描注册bean的基本使用以及进阶用法和@Componet及其衍生注解使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2022-02-02
  • 整理很详细的Java正则表达式使用大全

    整理很详细的Java正则表达式使用大全

    这篇文章为大家整理了很详细的Java正则表达式使用大全,大家在使用Java正则表达式的时候可查阅这篇文章,认为不错的朋友可以收藏起来
    2015-12-12
  • SpringMVC使用@Valid注解进行数据验证的方法

    SpringMVC使用@Valid注解进行数据验证的方法

    本篇文章主要介绍了SpringMVC使用@Valid注解进行数据验证的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • java用接口、多态、继承、类计算三角形和矩形周长及面积的方法

    java用接口、多态、继承、类计算三角形和矩形周长及面积的方法

    这篇文章主要介绍了java用接口、多态、继承、类计算三角形和矩形周长及面积的方法,涉及java面向对象中类、接口、多态等的使用技巧,需要的朋友可以参考下
    2015-05-05

最新评论