校园课程助手【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);
    }
}

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

相关推荐
开开心心_Every10 分钟前
免费压缩软件WinRAR无弹窗、广告干扰
java·开发语言·前端·spring·智能手机·word·winrar
计算机毕设定制辅导-无忧学长13 分钟前
《基于微信小程序的个人智能刷题助手的设计与实现》
java·spring boot·mysql·微信小程序·uniapp·个人智能刷题助手系统
步行cgn27 分钟前
Spring MVC 中实现 request 域效果的几种方式
java·后端
Thomas.Sir29 分钟前
第3课:SpringBoot4.x 自动配置原理:@EnableAutoConfiguration底层源码剖析
java·spring boot
Rain的Java大神之路33 分钟前
MySQL 被高并发打爆?从定位到分库分表逐层拆解(含秒杀库存实战)
java·后端·面试
cc_瀚海知行36 分钟前
工具调用 6|助手什么时候该停下来?
java·服务器·前端·人工智能·python·ai
YDS82939 分钟前
Small Spring IOC篇:应用上下文实现和Bean的扩展
java·后端·spring
Pniubi41 分钟前
ConcurrentHashMap拆分线程池难点再讲
java·jvm
golang学习记42 分钟前
IDEA 的 Java 智能,现在跑到 Cursor 和 VS Code 里去了
java·ide·vscode·intellij-idea·claude code
devilnumber1 小时前
springboot的保护机制怎么实现的,为何能做到服务不宕机
java·spring boot·后端