校园课程助手【3】-使用枚举类封装异常优雅处理全局异常

接着2中登录模块补充一个点:

java 复制代码
//可以看到这里返回给前端控制器的是一个类而不是html页面
    public RespBean doLogin(@Valid LoginVo loginVo, HttpServletRequest request,HttpServletResponse response){
        return userService.doLogin(loginVo, request, response);
    }

首先:在本项目中,所有的Controller类返回给前端控制器的都是ResBean对象,下面是这个类的实现,属性包括返回代码,提示信息以及一个Object类。

java 复制代码
package com.example.seckilldemo.vo;
import lombok.Data;

/**
 * @Author wuyifan
 * @Date 2024/4/22 16:17
 * @Version 1.0
 */
@Data

public class RespBean {
    private long code;
    private String message;
    private Object object;

    public static RespBean success() {
        return new RespBean(RespBeanEnum.SUCCESS.getCode(), RespBeanEnum.SUCCESS.getMessage(), null);
    }

    public static RespBean success(Object object) {
        return new RespBean(RespBeanEnum.SUCCESS.getCode(), RespBeanEnum.SUCCESS.getMessage(), object);
    }

    public static RespBean error(RespBeanEnum respBeanEnum) {
        return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(), null);
    }

    public static RespBean error(RespBeanEnum respBeanEnum, Object object) {
        return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(), object);
    }

    public RespBean(long code, String message, Object object) {
        this.code = code;
        this.message = message;
        this.object = object;
    }

    public RespBean(){

    }

    public long getCode() {
        return code;
    }

    public void setCode(long code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }
}

其中返回代码和信息是自定义一个枚举类实现的,用于优雅的处理全局异常信息,其类代码如下:

java 复制代码
package com.example.seckilldemo.vo;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

/**
 * @Author wuyifan
 * @Date 2024/4/22 16:17
 * @Version 1.0
 */
@ToString
@Getter
@AllArgsConstructor
public enum RespBeanEnum {
    //通用
    SUCCESS(200, "SUCCESS"),
    ERROR(500, "服务端异常"),

    //登录模块
    LOGIN_ERROR(500210, "用户名或者密码不正确"),
    MOBILE_ERROR(500211, "手机号码格式不正确"),
    BIND_ERROR(500212, "参数校验异常"),
    MOBILE_NOT_EXIST(500213, "手机号码不存在"),
    PASSWORD_UPDATE_FAIL(500214, "更新密码失败"),
    SESSION_ERROR(500215, "用户SESSION不存在"),


    //秒杀模块
    EMPTY_STOCK(500500, "库存不足"),
    REPEATE_ERROR(500501, "该商品每人限购一件"),
    REQUEST_ILLEGAL(500502, "请求非法,请重新尝试"),
    ERROR_CAPTCHA(500503, "验证码错误,请重新输入"),
    ACCESS_LIMIT_REACHED(500504, "访问过于频繁,请稍后重试"),
    //订单模块5003xx
    ORDER_NOT_EXIST(500300, "订单不存在"),

    ;

    private final Integer code;
    private final String message;

    public Integer getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

最后:介绍本项目使用上述枚举类封装一个优雅的 Spring Boot 全局异常处理的过程。

即使用 @ControllerAdvice 和 @ExceptionHandler 处理全局异常:

  1. 新建异常信息实体类(即RespBean )
  2. 自定义异常类型。
    一般我们处理的都是 RuntimeException ,所以如果你需要自定义异常类型的话直接集成这个类就可以了。
java 复制代码
package com.example.seckilldemo.exception;

import com.example.seckilldemo.vo.RespBean;
import com.example.seckilldemo.vo.RespBeanEnum;

/**
 * 全局异常
 *
 * @author: wuyifan
 * @date 2024/5/2 5:32 下午
 * @ClassName: GlobalException
 */
public class GlobalException extends RuntimeException {

    private RespBeanEnum respBeanEnum;

    public RespBeanEnum getRespBeanEnum() {
        return respBeanEnum;
    }

    public void setRespBeanEnum(RespBeanEnum respBeanEnum) {
        this.respBeanEnum = respBeanEnum;
    }

    public GlobalException(RespBeanEnum respBeanEnum) {
        this.respBeanEnum = respBeanEnum;
    }
}
  1. 新建异常处理类
    我们只需要在类上加上@ControllerAdvice注解这个类就成为了全局异常处理类,当然你也可以通过 assignableTypes指定特定的 Controller 类,让异常处理类只处理特定类抛出的异常。
java 复制代码
package com.example.seckilldemo.exception;

import com.example.seckilldemo.vo.RespBean;
import com.example.seckilldemo.vo.RespBeanEnum;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


/**
 * 全局异常处理类
 *
 * @author: wuyifan
 * @date 2024/5/2 5:33 下午
 * @ClassName: GlobalExceptionHandler
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public RespBean ExceptionHandler(Exception e) {
        if (e instanceof GlobalException) {
            GlobalException exception = (GlobalException) e;
            return RespBean.error(exception.getRespBeanEnum());
        } else if (e instanceof BindException) {
            BindException bindException = (BindException) e;
            RespBean respBean = RespBean.error(RespBeanEnum.BIND_ERROR);
            respBean.setMessage("参数校验异常:" + bindException.getBindingResult().getAllErrors().get(0).getDefaultMessage());
            return respBean;
        }
//        System.out.println("异常信息" + e);
        return RespBean.error(RespBeanEnum.ERROR);
    }
}

这样使用枚举类优雅的封装异常信息,通过自定义异常类型,最后交给全局异常类处理就可以啦啦啦啦啦!

相关推荐
sino爱学习20 小时前
FastUtil 高性能集合最佳实践:让你的 Java 程序真正“快”起来
java·后端
.豆鲨包20 小时前
【Android】 View事件分发机制源码分析
android·java
北京地铁1号线20 小时前
数据结构:堆
java·数据结构·算法
百***864620 小时前
Spring Boot应用关闭分析
java·spring boot·后端
tanxiaomi20 小时前
Spring、Spring MVC 和 Spring Boot ,mybatis 相关面试题
java·开发语言·mybatis
弥巷20 小时前
【Android】常见滑动冲突场景及解决方案
android·java
间彧20 小时前
GraalVM 深度解析:下一代 Java 技术平台
java
合作小小程序员小小店21 小时前
网页开发,在线%旧版本旅游管理%系统,基于eclipse,html,css,jquery,servlet,jsp,mysql数据库
java·数据库·servlet·eclipse·jdk·旅游·jsp
20岁30年经验的码农21 小时前
Java Sentinel流量控制与熔断降级框架详解
java·开发语言·sentinel
程序员西西21 小时前
SpringBoot轻松整合Sentinel限流
java·spring boot·后端·计算机·程序员