全局异常处理_springboot 教你如何更加优雅的处理全局异常

news/2024/7/8 1:36:02

 众所周知,现在的项目开发基本上都是前后端分离,而前后端分离之后,无论在控制层,还是业务层都需要校验一些数据,无论是前端传过来的,还是经过业务处理判断的,如果不合法的需要友好的提示给用户,否则用户收到一个 NullPointerException 这种的,懂开发的肯定一眼看出来,这还不简单,不就是个空指针嘛,但是对不懂开发的人来说呢?肯定很懵逼,再说直接将错误的信息直接暴露给用户,这样的体验可想而知。

今天就针对 springboot 做一次统一的异常处理

ce7647970eb141142d857b2eafba1aa4.png

  • 今日安利好物:springboot 全局异常处理

  • 全局异常处理有什么好处?

    当你自定义了一个异常类,可以在全局异常处理器中来捕捉该异常。当然也可以直接在抛出异常处直接捕获,但是这样需要在每一个抛出的地方都写一次捕获代码,看起来不够美观且复用性不强,其他异常同理

文中需要用到的部分注解

@ControllerAdvice,是Spring3.2提供的新注解,它是一个 Controller 增强器,可对 controller 中被 @RequestMapping 注解的方法加一些逻辑处理,这里我们使用它来做全局异常处理。

@RestControllerAdvice ,ControllerAdvice 的增强版,包含了@ControllerAdvice 和 @ResponseBody 注解功能;默认处理所有 controller 中被 @RequestMapping注解的方法,并且返回的数据为 json 格式

@ExceptionHandler ,使用此注解来指定获取自定义异常类

项目层级如下

a8d38fc3fb6d6d1bff29a5a76a798f59.png

01

定义自己的统一返回异常类

1、BaseException  继承  RuntimeException

原因:spring 对于 RuntimeException 异常才会进行事务回滚

package com.wxw.springboot_exception.exception;/** * @author wuxiongwei * @date 2020/5/27 10:45 * @Description */public class BaseException extends RuntimeException {    private static final long serialVersionUID = 4397143116579765052L;    /**     * 错误代码     */    private String code;    /**     * 错误信息     */    private String message;    public String getCode() {        return code;    }    public void setCode(String code) {        this.code = code;    }    public String getMessage() {        return message;    }    public void setMessage(String message) {        this.message = message;    }}

2、定义  CustomException  继承刚才的 BaseException

package com.wxw.springboot_exception.exception;/** * @author wuxiongwei * @date 2020/5/27 10:57 * @Description */public class CustomException extends BaseException {    private static final long serialVersionUID = -7796809450875600938L;    public CustomException(String code,String message) {        setCode(code);        setMessage(message);    }    public CustomException(String message) {        setCode("");        setMessage(message);    }    public CustomException() {    }}

3、使用断言封装部分方法,取代 if 判断,返回相应异常

平时,我们可能会写很多的 if 判断,来判断这个是不是空,那个是不是空,

使用这种方式可以极大简化我们的 if 判断,并且使我们的代码更加优雅

package com.wxw.springboot_exception.exception;/** * @author wuxiongwei * @date 2020/5/27 10:57 * @Description */public class CustomException extends BaseException {    private static final long serialVersionUID = -7796809450875600938L;    public CustomException(String code,String message) {        setCode(code);        setMessage(message);    }    public CustomException(String message) {        setCode("");        setMessage(message);    }    public CustomException() {    }}

02

定义全局异常信息处理统一返回类

1、异常返回信息对象

package com.wxw.springboot_exception.base;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;/** * @author wuxiongwei * @date 2020/5/27 11:07 * @Description 接口返回统一封装类 */@Data@NoArgsConstructor@AllArgsConstructor@Builderpublic class ResultResponse {    /**     * 返回状态码     */    private Integer status;    /**     * 返回信息     */    private String message;    /**     * 返回数据     */    private T data;    /**     * token     */    private String token;}

2、返回信息对象中用到的枚举类

package com.wxw.springboot_exception.Enums;/** * @author wuxiongwei * @date 2020/5/27 11:25 * @Description */public enum ResultCodeEnum {    SUCCESS(200,"请求成功"),    FAILURE(500,"请求失败"),    ;    private Integer code;    private String message;    ResultCodeEnum(Integer code, String message) {        this.code = code;        this.message = message;    }    public Integer getCode() {        return code;    }    public void setCode(Integer code) {        this.code = code;    }    public String getMessage() {        return message;    }    public void setMessage(String message) {        this.message = message;    }}

3、全局异常处理类

package com.wxw.springboot_exception.exception;import com.wxw.springboot_exception.Enums.ResultCodeEnum;import com.wxw.springboot_exception.base.ResultResponse;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RestControllerAdvice;/** * 统一全局异常处理类 */@RestControllerAdvice //ControllerAdvice 的增强版,包含了@ControllerAdvice 和 @ResponseBody 注解功能;默认处理所有 controller 中被 @RequestMapping注解的方法//@RestControllerAdvice(basePackages = "com.wxw.springboot_exception.controller") //指定处理 controller 包//@RestControllerAdvice(basePackageClasses = BController.class) // 指定处理的 controller 类//@ControllerAdvice()public class GlobalMyExceptionHandler {    @ExceptionHandler(value = CustomException.class)//使用此注解来指定获取自定义异常类,返回给前端 json 格式错误数据    public ResultResponse handlerException(CustomException e){        return ResultResponse.builder().status(ResultCodeEnum.FAILURE.getCode()).message(e.getMessage()).build();    }}

03

具体代码中抛出我们自定义的异常

1、定义测试抛出异常的 controller

package com.wxw.springboot_exception.controller;import com.wxw.springboot_exception.Enums.ResultCodeEnum;import com.wxw.springboot_exception.base.Assert;import com.wxw.springboot_exception.base.ResultResponse;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;/** * @author wuxiongwei * @date 2020/5/27 11:14 * @Description */@RestController@RequestMapping("/test")public class TestController {    @GetMapping("/test")    public ResultResponse test(){        //使用断言方法,取代 if 判断,同时抛出异常        Assert.assertTrue(1 == 1,"TEST测试异常");        return  ResultResponse.builder().status(ResultCodeEnum.SUCCESS.getCode()).message(ResultCodeEnum.SUCCESS.getMessage()).data("hello").build();    }}

2、使用 postman 请求接口,进行测试,可以看到我们测试的异常已经被以 json 数据返回出来了,证明我们自定义异常已经成功被拦截处理。

7bbd6cb5eedd057ead7e085f9bb1142e.png

7c1e31c9ab505e2b5f6534ba38be80f4.png

点击此处留言或查看留言


http://www.niftyadmin.cn/n/3661284.html

相关文章

[领域]Javascript Hacking Guide part 1

2007年02月01日 20:09:00 那天听东东将javascript,他讲得也匆忙,我听得也犯晕,心想如果能够建立起javascript的内存对象模型该多好啊。可是在网上找了好久,也没有发现javascript的Hacking guide,不经意间,却…

addeventlistener事件第三个参数_通过几个例子来理解 React 的事件系统

来源:Aaaaaaaaaaayouhttps://juejin.im/post/6863083643427979271说明:本文结论均基于 React 16.13.1 得出,若有出入请参考对应版本源码几个题目我们先来看几个题目,如果你都能很确定的说出结果,那么这篇文章就不用看了…

为取经而来_唐僧为什么冒着生命危险去为李世民取经,李世民的目的又是什么?...

唐僧去西天取经,是为了李世民,这跟他的追求没有一点关系,作为臣子的盲目崇拜也好,还是作为下属的无知感动也罢,反正去西天取这个经,不是自己本身的意图。那李世民为什么听了观音菩萨的一席话就决定派人去西…

[个人] 确立了新的研究方向

2007年01月31日 13:41:00 昨天晚上,听了wang的javascript和jodo的培训,他讲得更多的是技巧,所以很多人没有听懂,不过我找到了被他忽略了但我很感兴趣的点:javascript的内存模型。感觉好像又回到了若干年前那个意气风发…

html生成器_一本道生成器Python版,笑喷了

今天皮一下,众所周知,一本道是一本正经的胡说八道的简称,想必写过议论文的小伙伴,都知道引经据典是议论文高分必备,套上名人的话更加具有说服力是语文老师必教的知识点。所以呢,今天介绍的这个生成器就走的…

nslookup 包含在那个包中_nslookup命令详解

Nslookup 是一个监测网络中DNS服务器是否能正确实现域名解析的命令行工具。它在 Windows NT/2000/XP 中均可使用,但在Windows 98中却没有集成这一个工具。Nslookup 必须要安装了TCP/IP 协议的网络环境之后才能使用。现在网络中已经架设好了一台 DNS 服务器,主机名称…

[豆趣]成长日记

2007年01月16日 21:36:00 豆跟豆娘对话:"什么叫男儿?"豆娘说:"男儿就是泛指男同志,比方说男儿当自强啊。",豆一指豆娘:"那,你是女儿啦"--…

[豆趣]世界上仅存5只恐龙

2007年01月03日 20:26:00 元旦放了天假,火急火燎的赶回家,恰好,给豆在网上淘的《恐龙世纪》也到了,这家伙缠着我要恐龙也有些时日了,本来不想给他买的,可是豆娘说:"总比喜欢奥特曼什么的强…