【SpringBoot学习】26、SpringBoot 全局异常处理

本文介绍了如何在SpringBoot中实现全局的消息、异常和响应处理。通过定义枚举来管理状态码和信息,降低了耦合度,提高了代码复用。全局响应处理确保了后台返回数据的一致性,而全局异常处理则提供了友好的错误提示,增强了用户体验。此外,还分享了如何自定义全局异常类和异常处理器以增强系统的健壮性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringBoot 全局处理

全局消息处理

通常情况下,我们系统并不会考虑将文字描述等信息通过后台返回,我这样设计的好处就是如果以后需要前后端分离,并不会对整体结构造成影响。

/**
 * 异常枚举类
 *
 * @author Tellsea
 * @date 2019/7/13
 */
@AllArgsConstructor
public enum StatusEnums {

    /**
     * 业务枚举
     */
    LAYUI_SUCCESS(0, "加载成功"),
    SAVE_SUCCESS(200, "新增成功"),
    DELETE_SUCCESS(200, "删除成功"),
    UPDATE_SUCCESS(200, "修改成功"),
    SELECT_SUCCESS(200, "查询成功"),
    SAVE_ERROR(500, "新增失败"),
    DELETE_ERROR(500, "删除失败"),
    UPDATE_ERROR(500, "修改失败"),
    SELECT_ERROR(500, "查询失败"),
    /**
     * 系统枚举
     */
    UNAUTHORIZED(403, "未授权"),
    NOT_FOUND(404, "请求资源不存在"),
    USER_NOT_FOUND(500, "用户不存在"),
    PARAM_NOT_NULL(500, "参数不能为空"),
    CAPTCHA_ERROR(500, "验证码错误"),
    PASSWORD_ERROR(500, "密码错误"),
    SERVER_ERROR(500, "服务器累了,休息一会吧!"),
    ;

    @Setter
    private int code;

    @Setter
    private String info;


    @Override
    public int getCode() {
        return code;
    }

    @Override
    public String getInfo() {
        return info;
    }
}

扩展枚举

通过上面的配置状态码与信息,能解决所有的返回问题,同时衍生出了新的问题,假设我有一千个业务,针对业务的详细描述大概就是四千种,同时在一个类中定义所有的状态枚举就不符合我们的开发逻辑,高耦合,低内聚。

首先定义一个根接口,然后让相关的枚举类继承该接口,例如状态枚举、系统枚举、商品枚举等

/**
 * 枚举根接口
 *
 * @author Tellsea
 * @date 2019/8/5
 */
public interface BaseEnums {

    /**
     * 获得状态码
     *
     * @return
     */
    int getCode();

    /**
     * 获得消息
     *
     * @return
     */
    String getInfo();
}

改造我们上面的异常枚举类

public enum StatusEnums implements BaseEnums {

}

最后在使用时,我们的枚举参数统一使用 BaseEnums ,这样就可以传各种枚举的数据进行返回了。

全局响应处理

通常情况下,我们将后台的所有返回值都指定到特定的格式中,这样让整个开发团队协调性得到很大的提升,在前后端分离中能看出最显著的效果。下面是定义的全局返回结果集,为了提高效率,采用的是单例模式。(这里有一个坑,前后端分离网络卡顿的时候,返回值可能会错乱)

/**
 * 全局返回结果集
 *
 * @author Tellsea
 * @date 2019/7/13
 */
@Data
public class ResponseResult {

    private int code;
    private String message;
    private Object data;
    private static volatile ResponseResult instance;

    public static ResponseResult build(BaseEnums enums) {
        ResponseResult result = getInstance();
        result.code = enums.getCode();
        result.message = enums.getInfo();
        result.data = null;
        return result;
    }

    public static ResponseResult build(BaseEnums enums, Object data) {
        ResponseResult result = getInstance();
        result.code = enums.getCode();
        result.message = enums.getInfo();
        result.data = data;
        return result;
    }

    public static ResponseResult getInstance() {
        if (null == instance) {
            synchronized (ResponseResult.class) {
                if (null == instance) {
                    instance = new ResponseResult();
                }
            }
        }
        return instance;
    }
}

全局异常处理

通常情况下,我们都会重写系统默认的异常处理,修改抛出异常后的异常通知,从而达到对用户的友好提示,增加用户的体验度。

  • 自定义全局异常
/**
 * 全局异常
 *
 * @author Tellsea
 * @date 2019/7/13
 */
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class GlobalException extends RuntimeException {

    private BaseEnums baseEnums;
}
  • 全局异常处理器
/**
 * 全局异常处理
 *
 * @author Tellsea
 * @date 2019/7/13
 */
@Slf4j
@ControllerAdvice
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class GlobalExceptionHandle {

    @ExceptionHandler(value = Exception.class)
    public String exception(Exception e, Model model) {
        model.addAttribute("class", e.getClass());
        model.addAttribute("message", e.getMessage());
        log.error("【错误原因】{}", e.getClass());
        log.error("【错误描述】{}", e.getMessage());
        e.printStackTrace();
        return "admin/error";
    }

    @ExceptionHandler(value = GlobalException.class)
    public String globalExceptionHandle(GlobalException e, Model model) {
        model.addAttribute("class", e.getClass());
        model.addAttribute("message", e.getMessage());
        log.error("【错误原因】{}", e.getClass());
        log.error("【错误描述】{}", e.getMessage());
        e.printStackTrace();
        return "admin/error";
    }
}

提示:这里结合了全局消息处理、全局响应处理模块

技术分享区

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tellsea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值