SpringBoot:如何优雅地处理全局异常?

SpringBoot:如何优雅地处理全局异常?

之前用springboot的时候,只知道捕获异常使用try{}catch,一个接口一个try{}catch,这也是大多数开发人员异常处理的常用方式,虽然屡试不爽,但会造成一个问题,就是一个Controller下面,满屏幕的try{}catch,看着一点都不优雅,一点都不符合×××的气质,憋了这么久,×××今天终于决定对所有异常实施统一处理的方案。

开发准备

JDK8、正常的springboot项目

代码编写

通用异常处理

其实Spring系列的项目全局异常处理方式早已存在,只不过我们一直忙于搬砖,很少停下脚步去审视这个日夜与我们相伴的朋友。为了贴合主题,本次主要针对SpringBoot全局异常处理进行举例说明。

SpringBoot中有一个@ControllerAdvice的注解,使用该注解即表示开启全局异常捕获,接下来我们只需在自定义的方法上使用@ExceptionHandler注解,并定义捕获异常的类型,对这种类型的异常进行统一的处理。

举个例子:

假如我们需要针对NullException(空指针异常,是Java程序员最痛恨的异常,没有之一)进行全局处理(如下所示)。

@RestControllerAdvice
public class GlobalExceptionHandler {
        /**
     * 处理空指针的异常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value =NullPointerException.class)
    public BaseResponseFacade exceptionHandler(HttpServletRequest req, NullPointerException e){
        log.error("发生空指针异常!原因是:",e);
        return ResponseUtil.error(ResponseCode.ERROR);
    }
}

讷,就这么简单。其他可能发生的异常,都可以以这种方式处理快速处理。此处大家应该表现的十分兴奋,但请不要高兴太早,因为接下来,有更令激动人心的事情。

自定义异常处理

自定义一个异常
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;

/**
 * @Description 自定义异常
 * @Date 2019-08-05 15:49
 * @Created by 程序员×××
 */
@Data
@AllArgsConstructor
@Accessors(chain = true)
public class BizException extends RuntimeException {
    /**
     * 错误码
     */
    protected Integer errorCode;
    /**
     * 错误信息
     */
    protected String errorMsg;
}

显而易见,这个异常继承了RuntimeException,属于运行时异常。细心的朋友已经发现,我使用了Lombok插件,非常契合今天的主题,给大家简单介绍一下:

lombok是一个可以帮助我们简化java代码编写的工具类,尤其是简化javabean的编写,即通过采用注解的方式,消除代码中的构造方法,getter/setter等代码,使我们写的类更加简洁(如果使用的IDE是idea,需要安装插件哈)。

定义过之后,我们就可以和之前处理NullException方式一样处理我们自定义的异常。包括处理其他异常,都是这种方式。直接贴代码。

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理自定义的业务异常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = BizException.class)
    public BaseResponseFacade bizExceptionHandler(HttpServletRequest req, BizException e){
        log.error("发生业务异常!原因是:{}",e.getErrorMsg());
        return ResponseUtil.error(e.getErrorCode(),e.getErrorMsg());
    }

    /**
     * 处理空指针的异常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value =NullPointerException.class)
    public BaseResponseFacade exceptionHandler(HttpServletRequest req, NullPointerException e){
        log.error("发生空指针异常!原因是:",e);
        return ResponseUtil.error(ResponseCode.ERROR);
    }

    /**
     * 处理其他异常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value =Exception.class)
    public BaseResponseFacade exceptionHandler(HttpServletRequest req, Exception e){
        log.error("未知异常!原因是:",e);
        return ResponseUtil.error(ResponseCode.INTERNAL_SERVER_ERROR);
    }
}

整个全局异常处理方式核心就是以上介绍这些。下面用一个Demo给大家举个例子

@GetMapping("/test")
public BaseResponseFacade test(){
  if(true){
    throw new BizException(1,"error");
  }
  return ResponseUtil.success();
}

地址栏请求,进入这个方法后,会抛出异常,此时全局异常生效,就会返回异常处理过后的信息

{"errorCode":1,"errorMsg":"error","data":null}

到此整个流程都然跑通了。当然,好多地方都可以根据我们自身实际业务情况以此为基础进一步丰富,比如返回数据可以改成跳转某一个具体的页面。这样的出场方式是不是都很优雅?大家有什么问题,期待各位留言。

原文地址:https://blog.51cto.com/14494819/2428318

时间: 2024-08-28 21:40:13

SpringBoot:如何优雅地处理全局异常?的相关文章

springBoot(5)---单元测试,全局异常

单元测试,全局异常 一.单元测试 1.基础版 1.引入相关依赖 <!--springboot程序测试依赖,如果是自动创建项目默认添加--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </depen

SpringBoot(6) SpringBoot配置全局异常

1.全局异常 @ControllerAdvice 如果是返回json数据 则用 RestControllerAdvice,就可以不加 @ResponseBody //捕获全局异常,处理所有不可知的异常 @ExceptionHandler(value=Exception.class) 1 @RestControllerAdvice 2 public class CustomExtHandler { 3 4 private static final Logger LOG = LoggerFactor

springboot编程之全局异常捕获

springboot编程之全局异常捕获 1.创建GlobalExceptionHandler.java,在类上注解@ControllerAdvice, 在方法上注解@ExceptionHandler(value = Exception.class),Exception.class表示拦截所有的异常信息 package com.imooc.web.controller; import com.imooc.exception.UserNotExistException; import org.spr

Eclipse搭建springboot项目(六)全局异常

知识点: 1.SpringBoot2.x服务端异常和SpringBoot配置全局异常 1).默认异常测试 int i = 1/0,不友好 2).异常注解介绍 @ControllerAdvice 如果是返回json数据 则用 RestControllerAdvice,就可以不加 @ResponseBody //捕获全局异常,处理所有不可知的异常 @ExceptionHandler(value=Exception.class) 2.SpringBoot2.x配置全局异常返回自定义异常和错误页面跳转

springboot捕获全局异常和配置多数据源

目录 配置多数据源 写两个数据源的配置类. @(springboot捕获全局异常和配置多数据源) 捕获全局异常是在项目运行期间如果调用的某一个方法出现了运行时异常,则会捕获,并且给出回馈. 首先需要建一个包,包里新建一个捕获异常类GlobalExceptionHandler.前提是springboot的启动类的扫描注解ComponentScan()要扫描到. /** * 用于捕获全局异常 */ @ControllerAdvice//控制器切面 public class GlobalExcepti

170621、springboot编程之全局异常捕获

1.创建GlobalExceptionHandler.java,在类上注解@ControllerAdvice,在方法上注解@ExceptionHandler(value = Exception.class),Exception.class表示拦截所有的异常信息 package com.rick.common.handler; import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.util.IOUtils;import com.r

【spring】-- springboot配置全局异常处理器

一.为什么要使用全局异常处理器? 什么是全局异常处理器? 就是把错误异常统一处理的方法. 应用场景: 1.当你使用jsr303参数校验器,如果参数校验不通过会抛异常,而且无法使用try-catch语句直接捕获,这时可以使用全局异常处理器来捕捉该异常. 2.当你自定义了一个异常类,可以在全局异常处理器中来捕捉该异常.(当然也可以直接在抛出异常处直接捕获,但是这样需要在每一个抛出的地方都写一次捕获代码,看起来不够美观且复用性不强,其他异常同理). 所有异常都可以在全局异常处理器中捕获进行统一处理 二

Spring Boot 中全局异常处理器

Spring Boot 中全局异常处理器,就是把错误异常统一处理的方法.等价于Springmvc中的异常处理器. 步骤一:基于前面的springBoot入门小demo修改 步骤二:修改HelloController类 修改HelloController,使得访问/hello一定会产生异常: some exception package cn.xdf.springboot.web; import java.text.DateFormat; import java.util.Date; import

爱上MVC~业务层刻意抛出异常,全局异常的捕获它并按格式返回

对于业务层的程序的致命错误,我们一直的做法就是直接抛出指定的异常,让程序去终断,这种做法是对的,因为如果一个业务出现了致命的阻塞的问题,就没有必要再向上一层一层的返回了,但这时有个问题,直接抛异常,意味着服务器直接500了,前端如何去显示,或者如果你是API的服务,如果为前端返回,如果是500,那直接就挂了,哈哈! 下面是在MVC环境下优化的全局异常捕获代码(非API) /// <summary> /// 全局异常捕获 /// </summary> public class Glo