前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >SpringBoot系列(九)统一异常处理与统一结果返回

SpringBoot系列(九)统一异常处理与统一结果返回

作者头像
全栈学习笔记
发布于 2022-03-31 03:40:49
发布于 2022-03-31 03:40:49
2.4K00
代码可运行
举报
文章被收录于专栏:全栈学习笔记全栈学习笔记
运行总次数:0
代码可运行

目录

  • 1. 全局异常捕获与处理
  • 2. 统一结果返回与统一异常
  • 3. controller代码测试与结果
  • 4. 404异常特殊处理。
  • 5. 总结

引言

 日常开发过程中,难免有的程序会因为某些原因抛出异常,而这些异常一般都是利用try ,catch的方式处理异常或者throw,throws的方式抛出异常不管。这种方法对于程序员来说处理也比较麻烦,对客户来说也不太友好,所以我们希望既能方便程序员编写代码,不用过多的自己去处理各种异常编写重复的代码又能提升用户的体验,这时候全局异常处理就显得很重要也很便捷了,是一种不错的选择。

1. 全局异常捕获与处理

因为现在主流的都是前后端分离的项目,所以我们的异常处理也根据前后端分离来讲述。

 Springboot对于异常的处理也做了不错的支持,它提供了一个 @ControllerAdvice注解以及 @ExceptionHandler注解,前者是用来开启全局的异常捕获,后者则是说明捕获哪些异常,对那些异常进行处理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@ControllerAdvice
public class MyExceptionHandler {

    @ExceptionHandler(value =Exception.class)
  public String exceptionHandler(Exception e){
    System.out.println("发生了一个异常"+e);
         return e.getMessage();
    }
}

上面这段代码就是说,只要是代码运行过程中有异常就会进行捕获,并输出出这个异常。然后我们随便编写一个会发生异常的代码,测试出来的异常是这样的。  

这对于我们前后端分离来说并不好,前后端分离之后唯一的交互就是json了,我们也希望将后端的异常变成json返回给前端处理。下面我们看看统一结果处理。

2. 统一结果返回与统一异常

代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Result<T> {
    //是否成功
    private Boolean success;
    //状态码
    private Integer code;
    //提示信息
    private String msg;
    //数据
    private T data;
    public Result() {

    }
    //自定义返回结果的构造方法
    public Result(Boolean success,Integer code, String msg,T data) {
        this.success = success;
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    //自定义异常返回的结果
    public static Result defineError(DefinitionException de){
        Result result = new Result();
        result.setSuccess(false);
        result.setCode(de.getErrorCode());
        result.setMsg(de.getErrorMsg());
        result.setData(null);
        return result;
    }
    //其他异常处理方法返回的结果
    public static Result otherError(ErrorEnum errorEnum){
        Result result = new Result();
        result.setMsg(errorEnum.getErrorMsg());
        result.setCode(errorEnum.getErrorCode());
        result.setSuccess(false);
        result.setData(null);
        return result;
    }
}

 说明:其中省略了get,set方法。另外方法之中包含了一个自定义的枚举。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public enum ErrorEnum {
  // 数据操作错误定义
  SUCCESS(200, "nice"),
  NO_PERMISSION(403,"你没得权限"),
  NO_AUTH(401,"你能不能先登录一下"),
  NOT_FOUND(404, "未找到该资源!"),
  INTERNAL_SERVER_ERROR(500, "服务器跑路了"),
  ;

  /** 错误码 */
  private Integer errorCode;

  /** 错误信息 */
  private String errorMsg;

  ErrorEnum(Integer errorCode, String errorMsg) {
    this.errorCode = errorCode;
    this.errorMsg = errorMsg;
  }

    public Integer getErrorCode() {
        return errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }
}

说明:枚举类中定义了常见的错误码以及错误的提示信息。这里我们就定义好了统一的结果返回,其中里面的静态方法是用来当程序异常的时候转换成异常返回规定的格式。

 然后我们需要自定义异常处理类。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class DefinitionException extends RuntimeException{

    protected Integer errorCode;
    protected String errorMsg;

    public DefinitionException(){

    }
    public DefinitionException(Integer errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    public Integer getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(Integer errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }
}

其中包含了错误的状态码,错误的提示信息。然后我们可以自定义一个全局异常处理类,来处理各种异常,包括自己定义的异常和内部异常。这样可以简化不少代码,不用自己对每个异常都使用try,catch的方式来实现。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理自定义异常
     *
     */
    @ExceptionHandler(value = DefinitionException.class)
    @ResponseBody
    public Result bizExceptionHandler(DefinitionException e) {
        return Result.defineError(e);
    }

    /**
     * 处理其他异常
     *
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result exceptionHandler( Exception e) {
        return Result.otherError(ErrorEnum.INTERNAL_SERVER_ERROR);
    }
}

说明:每个方法上面加上一个 @ResponseBody的注解,用于将对象解析成json,方便前后端的交互,也可以使用 @ResponseBody放在异常类上面。

3. controller代码测试与结果

 controller代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RestController
@RequestMapping("/result")
public class ResultController {
    @GetMapping("/getStudent")
    public Result getStudent(){
        Student student = new Student();
        student.setAge(21);
        student.setId(111);
        student.setName("学习笔记");
        Result result = new Result();
        result.setCode(200);
        result.setSuccess(true);
        result.setData(student);
        result.setMsg("学生列表信息");
        return result;
    }
    @RequestMapping("/getDeException")
    public Result DeException(){
        throw new DefinitionException(400,"我出错了");
    }
    @RequestMapping("/getException")
    public Result Exception(){
        Result result = new Result();
        int a=1/0;
        return result;
    }
}

 其中的Student类就是前面一直在用的类了。包含三个属性。其中省略了get,set方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Student  {
    /**
    * 唯一标识id
    */
    private Integer id;
    /**
    * 姓名
    */
    private String name;
    /**
    * 年龄
    */
    private Integer age;

}

然后启动项目,来挨个测试。首先测试正常没有异常发生的数据。浏览器输入:localhost:8095/result/getStudent  

可以看到数据是正常返回json串。没有异常。然后我们测试第二个自定义异常处理接口。浏览器输入localhost:8095/result/getDeException。

可以看到这个自定义的异常是捕获到了,并且返回了一个json串。最后我们测试一下其他的异常。浏览器输入:localhost:8095/result/getException

到这里我们就处理完了异常并且正确的返回了前端。这里说一下,测试接口有很多方法,可以使用postman,或者idea自带的接口测试工具都很好用。

 但是,你可能会发现一个问题,这种方法是不能处理404异常的,捕获不到。该怎么办呢?

4. 404异常特殊处理。

默认情况下,SpringBoot是不会抛出404异常的,所以**@ControllerAdvice**也不能捕获到404异常。我们可以通过以下配置来让这个注解能捕获到404异常。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

其中第一句是表示:当发现404异常时直接抛出异常。第二句关闭默认的静态资源路径映射。这样404错误也能被捕获到,但是这个配置会让你的静态资源访问出现问题,也就是不适合前后端不分离的情况。

5. 总结

本文讲解了如何处理捕获全局异常以及怎么自定义异常,顺便说明了统一结果的返回格式,并特殊处理的404,not found的异常,将其作为统一结果返回。如果你觉得本文有用,

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
公司这套架构统一处理try...catch这么香,求求你不要再满屏写了,再发现扣绩效!
软件开发springboot项目过程中,不可避免的需要处理各种异常,spring mvc 架构中各层会出现大量的try {...} catch {...} finally {...} 代码块,不仅有大量的冗余代码,而且还影响代码的可读性。这样就需要定义个全局统一异常处理器,以便业务层再也不必处理异常。
程序员白楠楠
2020/12/16
4990
看看别人家 SpringBoot 的全局异常处理,多么优雅....
> 公众号:[Java小咖秀](https://t.1yb.co/jwkk),网站:[javaxks.com](https://www.javaxks.com)
Java小咖秀
2021/04/18
4510
看看别人家 SpringBoot 的全局异常处理,多么优雅....
SpringBoot2.3.12.RELEASE优雅的全局异常处理(模板一)
参考:https://www.cnblogs.com/xuwujing/p/10933082.html
别先生
2021/07/01
7940
springboot搞定全局自定义异常
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说springboot搞定全局自定义异常,希望能够帮助大家进步!!!
Java架构师必看
2021/11/30
4360
springboot项目自定义统一异常处理
异常指的是在程序运行过程中发生的异常事件,通常是由外部问题(如硬件错误、输入错误)所导致的。在Java等面向对象的编程语言中异常属于对象
许喜朝
2021/02/04
1.6K0
SpringBoot全局异常处理
估计大家都会了的^_^,本文代码为主,在做Web应用的时候,请求处理过程中发生错误是非常常见的情况,那我们如何才能统一且友好地返回系统异常给前台呢。
用户3467126
2019/08/16
8080
SpringBoot全局异常处理
写了这么久的业务连异常都不知道怎么处理吗
hi ,大家好,我是三天打鱼,两天晒网的小六六,欢迎大家关注我的公众号:"六脉神剑的程序人生",一起学习,一起进步
用户9927510
2022/07/29
3050
写了这么久的业务连异常都不知道怎么处理吗
从零开始做网站8-全局异常处理和使用mybatis-plus分页插件
全局异常处理用于前端统一错误显示,还有就是后端分页插件,使用的mybatisplus。
sunonzj
2022/06/21
6420
从零开始做网站8-全局异常处理和使用mybatis-plus分页插件
Spring Boot配置全局异常处理器
创建自定义异常类原因:java自己的异常类只有message参数,这里我们还需要一个code参数(用来记录请求状态)。并且创建自定义异常还能和系统异常区分开来。
良月柒
2019/03/19
1.3K0
Spring Boot配置全局异常处理器
SpringBoot:优雅地处理全局异常
其实Spring系列的项目全局异常处理方式早已存在,只不过我们一直忙于搬砖,很少停下脚步去审视这个日夜与我们相伴的朋友。为了贴合主题,本次主要针对SpringBoot全局异常处理进行举例说明。
程序员小明
2019/08/14
7860
Spring Boot统一异常处理
先定义接口返回数据结构,code为0表示操作成功,非0表示异常。其中data只有在处理成功才会返回,其他情况不会返回,或者那些不需要返回数据的接口(更新、删除…)
用户7353950
2022/06/23
4560
Spring Boot统一异常处理
springboot(17)统一异常处理
使用Spring Boot统一处理异常。 本文实例是从数据库中根据ID查询学生信息,要求学生的年龄在14——20岁之间。小于14岁,提示“你可能在上初中”;大于20岁,提示“呢可能在上大学”。 第一步,创建枚举类ResultEnum,用来管理异常信息 package *;//自己定义 public enum ResultEnum { UNKONW_ERROR(-1, "未知错误"), SUCCESS(0, "成功"), PRIMARY_SCHOOL(100, "年龄小于14岁,可能正
IT架构圈
2018/05/31
8160
Spring学习笔记(二十一)——规范开发:SpringBoot表单验证、AOP切面编程、统一返回结果和异常处理
SpringMVC中使用Controller需要配合ResponseBody来返回json格式,springboot4后只需配置RestController就能实现返回json
不愿意做鱼的小鲸鱼
2022/09/26
6910
Spring学习笔记(二十一)——规范开发:SpringBoot表单验证、AOP切面编程、统一返回结果和异常处理
SpringBoot统一功能处理
本章是讲Spring Boot 统⼀功能处理模块,也是 AOP 的实战环节,要实现的目标有以下 3 个:
终有救赎
2023/10/16
2230
SpringBoot统一功能处理
Spring Boot 统一异常处理实战|文末送书
在Spring Boot项目中可以完成全局异常的统一处理,能够给用户提供友好的错误提示信息。下面演示本项目的异常处理过程。首先自定义异常: package com.example.thymeleafdemo.exception;import lombok.Data;/*** 自定义异常*/@Datapublic class MyBusinessException extendsRuntimeException { privatestatic final l
程序猿DD
2022/09/14
2540
Spring Boot 统一异常处理实战|文末送书
拿去用,接口统一返回值,最简单的一种实现
上一篇中介绍了 RequestBodyAdvice 接口,可以对@RequestBody 进行增强,本文介绍另外一个相似的接口:ResponseBodyAdvice,这个可以对@ResponseBody 进行增强,可以拦截@ResponseBody 标注的方法的返回值,对返回值进行统一处理,比如进行加密、包装等操作;比如通过他可以实现统一的返回值。
路人甲Java
2021/10/20
1.3K0
SpringBoot统一接口返回和全局异常处理
项目中最常见到的是封装一个工具类,类中定义需要返回的字段信息,把需要返回前端的接口信息,通过该类进行封装,这样就可以解决返回格式不统一的现象了。
用户7741497
2022/02/28
6760
统一异常处理这样剖析,安否?
「欲渡黄河冰塞川,将登太行雪满天」,无论生活还是计算机世界难免发生异常,上一篇文章RESTful API 返回统一JSON数据格式 说明了统一返回的处理,这是请求一切正常的情形;这篇文章将说明如何统一处理异常,以及其背后的实现原理,老套路,先实现,后说明原理,有了上一篇文章的铺底,相信,理解这篇文章就驾轻就熟了
用户4172423
2019/09/04
6130
统一异常处理这样剖析,安否?
关于后端统一数据格式的一点总结
最近在学SpringBoot的时候,偶然又看到了统一数据格式这一块的内容,所有打算写点东西总结一下。
秃头哥编程
2019/06/04
6700
关于后端统一数据格式的一点总结
SpringBoot自定义异常处理
code2roc
2023/07/19
2020
推荐阅读
相关推荐
公司这套架构统一处理try...catch这么香,求求你不要再满屏写了,再发现扣绩效!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验