阅读量:0
接着2中登录模块补充一个点:
//可以看到这里返回给前端控制器的是一个类而不是html页面 public RespBean doLogin(@Valid LoginVo loginVo, HttpServletRequest request,HttpServletResponse response){ return userService.doLogin(loginVo, request, response); }
首先:在本项目中,所有的Controller类返回给前端控制器的都是ResBean对象,下面是这个类的实现,属性包括返回代码,提示信息以及一个Object类。
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; } }
其中返回代码和信息是自定义一个枚举类实现的,用于优雅的处理全局异常信息,其类代码如下:
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 处理全局异常:
- 新建异常信息实体类(即RespBean )
- 自定义异常类型。
一般我们处理的都是 RuntimeException ,所以如果你需要自定义异常类型的话直接集成这个类就可以了。
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; } }
- 新建异常处理类
我们只需要在类上加上@ControllerAdvice注解这个类就成为了全局异常处理类,当然你也可以通过 assignableTypes指定特定的 Controller 类,让异常处理类只处理特定类抛出的异常。
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); } }
这样使用枚举类优雅的封装异常信息,通过自定义异常类型,最后交给全局异常类处理就可以啦啦啦啦啦!