1、为什么要全局异常处理

在实际开发中,如果不处理统一处理异常,那么前端在调用后端提供的接口,就会处理各种的异常结构,对于前端来说那可谓是一场灾难,这对前后端的协作也不友好。比如后端路径:/api/v1/index/user?id=222,如果前端未传入ID,那么SpringBoot就会报如下异常:

{"timestamp":"2021-03-30T15:22:46.139+00:00","status":400,"error":"Bad Request","message":"","path":"/api/v1/index/user"}

或者是我们代码里面自定义异常throw new RuntimeException("用户信息未找到!");,对于Spring Boot来说抛出如下异常:

{"timestamp":"2021-03-30T15:25:55.657+00:00","status":500,"error":"Internal Server Error","message":"","path":"/api/v1/index/users"}

而后端真的异常信息是用户信息未找到!,前端获取到500异常,完全不知后端的具体异常。基于这些就有必要全局统一处理异常。

2、实现全局异常处理

2.1 封装统一结构消息

在实现全局异常处理之前,我们先封装一个统一结构的消息对象。

  • 消息类
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class RestResponse {private String code;private String message;private Object data;
}
  • 异常状态枚举
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ExceptionStatusEnums {OK("0","success"),ERROR("1","error");private String code;private String msg;
}
  • 处理消息的工厂类
import com.tenghu.lf.enums.ExceptionStatusEnums;
import com.tenghu.lf.resp.RestResponse;public class ResponseFactory {private ResponseFactory(){}public static RestResponse getOkResponse(){return new RestResponse(ExceptionStatusEnums.OK.getCode(),ExceptionStatusEnums.OK.getMsg(),null);}public static RestResponse getOkResponse(String message){return new RestResponse(ExceptionStatusEnums.OK.getCode(),message,null);}public static RestResponse getOkResponse(Object data){return new RestResponse(ExceptionStatusEnums.OK.getCode(),ExceptionStatusEnums.OK.getMsg(),data);}public static RestResponse getOkResponse(String message,Object data){return new RestResponse(ExceptionStatusEnums.OK.getCode(),message,data);}public static RestResponse getErrorMessage(){return new RestResponse(ExceptionStatusEnums.ERROR.getCode(),ExceptionStatusEnums.ERROR.getMsg(),null);}public static RestResponse getErrorMessage(String message){return new RestResponse(ExceptionStatusEnums.ERROR.getCode(),message,null);}public static RestResponse getErrorMessage(String message,Object data){return new RestResponse(ExceptionStatusEnums.ERROR.getCode(),message,data);}public static RestResponse getBuildMessage(String code,String message){return new RestResponse(code,message,null);}public static RestResponse getBuildMessage(String code,String message,Object data){return new RestResponse(code,message,data);}
}

2.2 实现全局异常

定义一个全局异常处理类,在类上加上@RestControllerAdvice注解,也可以使用@ControllerAdvice注解,只不过使用后者,需要在各个方法上加上@ResponseBody注解

@RestControllerAdvice
public class GlobalExceptionHandler {/*** 处理自定义异常* @param componentException* @return*/@ExceptionHandler(ComponentException.class)public RestResponse componentException(ComponentException componentException) {componentException.printStackTrace();return ResponseFactory.getBuildMessage(componentException.getCode(),componentException.getLocalizedMessage());}/*** 处理请求参数异常* @param e* @return*/@ExceptionHandler(MissingServletRequestParameterException.class)public RestResponse paramMissingException(MissingServletRequestParameterException e){e.printStackTrace();return ResponseFactory.getBuildMessage(HttpStatus.INTERNAL_SERVER_ERROR.value()+"",String.format("请求参数:%s不能为空!",e.getParameterName()));}/*** 处理请求体异常* @param e* @return*/@ExceptionHandler(HttpMessageNotReadableException.class)public RestResponse readableException(HttpMessageNotReadableException e){e.printStackTrace();return ResponseFactory.getBuildMessage(HttpStatus.INTERNAL_SERVER_ERROR.value()+"",String.format("请求参数体不能为空!%s",e.getLocalizedMessage()));}/*** 处理其他未知的运行时异常* @param runtimeException* @return*/@ExceptionHandler(RuntimeException.class)public RestResponse runtimeException(RuntimeException runtimeException) {runtimeException.printStackTrace();return ResponseFactory.getBuildMessage(HttpStatus.INTERNAL_SERVER_ERROR.value()+"",runtimeException.getLocalizedMessage());}/*** 处理其他异常* @param exception* @return*/@ExceptionHandler(Exception.class)public RestResponse otherException(Exception exception){exception.printStackTrace();return ResponseFactory.getErrorMessage(exception.getLocalizedMessage());}
}

3、测试

  • 访问路径/api/v1/index/user?name=小A,不传name的情况下。
{"code": "500","message": "请求参数:name不能为空!","data": null
}
  • 访问路径/api/v1/index/user?name=小A,传name的情况下。
{"code": "0","message": "success","data": {"id": "1111","name": "小A"}
}
  • 访问路径/api/v1/index,不传请求体。
{"code": "500","message": "请求参数体不能为空!Required request body is missing: public com.tenghu.lf.resp.RestResponse com.tenghu.lf.controller.IndexController.save(com.tenghu.lf.entity.User)","data": null
}
  • 访问路径/api/v1/index,传请求体。
{"code": "0","message": "success","data": null
}

其他就不一一测试了,感兴趣的可以自己尝试下。

SpringBoot全局异常处理相关推荐

  1. springboot全局异常处理_SpringBoot:如何优雅地处理全局异常

    之前用springboot的时候,只知道捕获异常使用try{}catch,一个接口一个try{}catch,这也是大多数开发人员异常处理的常用方式,虽然屡试不爽,但会造成一个问题,就是一个Contro ...

  2. springboot 全局异常处理类

    目录标题 springboot 全局异常处理类 依赖 代码 springboot 全局异常处理类 依赖 <!-- Spring Boot Web 依赖 核心 --><dependen ...

  3. [SpringBoot]全局异常处理

    2019独角兽企业重金招聘Python工程师标准>>> 1. 全局异常处理 2. SpringBoot错误处理原理 3. SpringBoot定制错误页面 4. SpringBoot ...

  4. SpringBoot 全局异常处理

    下面首先来观察一个程序代码,例如:现在建立一个控制器,而后这个控制器自己抛出一个异常.@Controller public class MemberController extends Abstrac ...

  5. SpringBoot全局异常处理及前端请求参数校验

    SpringBoot全局异常捕获处理及参数校验 文章目录 SpringBoot全局异常捕获处理及参数校验 为什么要用全局异常处理? 如何进行全局异常捕获和处理? 统一结果封装 统一返回结果 枚举类 使 ...

  6. springBoot 全局异常处理 报错 : Could not resolve method parameter at index 0 in public .....

    在学习 springboot 的全局异常处理时   ,我写了一个处理异常类 @ControllerAdvice public class ErrorCatchController {@Exceptio ...

  7. springboot 全局异常处理 自定义mvc错误页面展示

    如下:所有的异常都会进入到这里.根据个人业务按需处理 全局异常处理 @ControllerAdvice public class ErrorAdviceController {//指定捕获对象@Exc ...

  8. springboot全局异常处理详解

    对于全局异常需要认识两个注解 @RestControllerAdvice,@ExceptionHandler 1. @RestControllerAdvice 组成:@ControllerAdvice ...

  9. springboot全局异常处理BasicErrorController和RestControllerAdvice

    文章目录 RestControllerAdvice BasicErrorController ResponseBodyAdvice RestControllerAdvice @RestControll ...

最新文章

  1. CMake常见指令总结
  2. 10个关于文件操作的小功能(Python),都很实用~
  3. Visual Studio 2010 C++ 工程文件解读
  4. 提示word损坏,需文本恢复转换器的解决两方法
  5. [转载] Docker网络原则入门:EXPOSE,-p,-P,-link
  6. 2018C/C++蓝桥杯解析
  7. java jsp网页计算器_使用jsp+javaBean写一个网页计算器
  8. 睡眠监测中的一些术语和指标(AASM)
  9. sqlhelper java_java版sqlhelper
  10. 数字日期格式转换yyyymmdd_js时间转换,能够把时间转换成yyyymmdd格式或yyyymm格式...
  11. 分布式集群中如何保证线程安全?
  12. uubox.net 网站的第二阶段完成,修复了部分的bug,增加了图片浏览和mp3在线播放等功能...
  13. Xcode8 解决注释以及VVDocumenter无法使用问题
  14. mac的 tr命令_tr命令 - Holy_Shit - 博客园
  15. 微信JS接口安全域名设置不成功,提示没有找到文件
  16. 空气净化器哪个品牌口碑好 空气净化器除甲醛排行榜前十名
  17. 618年中大促如何选择蓝牙耳机?值得买的蓝牙耳机品牌
  18. 那怎样的文档才是好的产品文档呢
  19. RRDTool中文手册
  20. 又见block(一):block是什么?

热门文章

  1. ARCGIS制作图中图——小图/一幅多图
  2. 【一天一个挨打小技巧】大黄蜂云课堂在听课时候做笔记,无法截图!安排
  3. CreateJS奥运五环动画
  4. python 空数组判断
  5. kotlin!腾讯+字节+阿里面经真题汇总,挥泪整理面经
  6. PHP汉字转拼音第三方类库
  7. 项目编译不成功原因之一的引用jar包问题
  8. 学生命科学要学计算机吗,生命科学属于什么门类 计算机科学与技术专业属于什么门类...
  9. 财务管理考研计算机,财务管理考研专业课包括什么
  10. python解决Failed building wheel for XXX