每日小知识点(三) - HTTP 状态码

每日小知识点(三) - HTTP 状态码

HTTP 状态码是用来表示 HTTP 请求的响应状态的数字代码。

2xx

3xx

4xx

5xx

一些处理状态码和异常的小技巧


/**
 * 响应枚举,用于异常的信息设置
 * @author xiaozhu
 * @date 2022年10月03日 23:40                          $
 */
public enum AppHttpCodeEnum {
    // 成功
    SUCCESS(200,"操作成功"),
    // 登录
    NEED_LOGIN(401,"需要登录后操作"),
    NO_OPERATOR_AUTH(403,"无权限操作"),
    SYSTEM_ERROR(500,"出现错误"),
    USERNAME_EXIST(501,"用户名已存在"),
    PHONENUMBER_EXIST(502,"手机号已存在"), EMAIL_EXIST(503, "邮箱已存在"),
    REQUIRE_USERNAME(504, "必需填写用户名"),
    NO_USER_ERROR(519,"用户不存在"),
    CONTENT_NOT_NULL(519,"评论不能为空"),
    PARAMETER_ERROR(1001, "请求参数有误!"),
    LOGIN_ERROR(505,"用户名或密码错误");


    int code;
    String msg;

    AppHttpCodeEnum(int code, String errorMessage){
        this.code = code;
        this.msg = errorMessage;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}
/**
 * 全局异常
 * @author xiaozhu
 * @date 2022年10月03日 23:40                          $
 */
public class SystemException extends RuntimeException{

    private int code;

    private String msg;

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public SystemException(AppHttpCodeEnum httpCodeEnum) {
        super(httpCodeEnum.getMsg());
        this.code = httpCodeEnum.getCode();
        this.msg = httpCodeEnum.getMsg();
    }

}

枚举类AppHttpCodeEnum中定义了一些常用的 HTTP 返回码,如成功返回码SUCCESS、需要登录返回码NEED_LOGIN等。每个返回码都有一个对应的状态码和错误信息,通过调用getCode()getMsg()方法可以获取相应的状态码和错误信息。

自定义异常类SystemException继承了 Java 的 RuntimeException 类,用于在程序运行过程中抛出异常。当抛出这个异常时,会调用AppHttpCodeEnum中定义的错误信息,并返回对应的状态码。同时,这个异常类还提供了获取状态码和错误信息的方法getCode()getMsg(),方便在程序中获取异常的信息。

这样设计的好处在于,当程序发生异常时,可以直接抛出SystemException异常,通过捕获异常获取到对应的状态码和错误信息,从而快速定位和解决问题。同时,使用枚举类定义 HTTP 返回码,可以方便地管理和扩展状态码。

/**
 * 全局捕获异常
 *
 * @author xiaozhu
 * @date 2022年10月03日 23:40                          $
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(SystemException.class)
    public ResponseResult systemExceptionHandler(SystemException e) {
        //打印异常信息
        log.error("出现了异常! : {}", e);
        //从异常对象中获取提示信息封装返回
        return ResponseResult.errorResult(e.getCode(), e.getMsg());
    }


    @ExceptionHandler(Exception.class)
    public ResponseResult exceptionHandler(Exception e) {
        //打印异常信息
        log.error("出现了异常! : {}", e);
        //从异常对象中获取提示信息封装返回
        return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR.getCode(), e.getMessage());
    }


    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseResult parameterExceptionHandler(MethodArgumentNotValidException e) {
        log.error("参数出现了异常! : {}", e);
        // 获取异常信息
        BindingResult exceptions = e.getBindingResult();
        // 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
        if (exceptions.hasErrors()) {
            List<ObjectError> errors = exceptions.getAllErrors();
            if (!errors.isEmpty()) {
                // 这里列出了全部错误参数,按正常逻辑,只需要第一条错误即可
                FieldError fieldError = (FieldError) errors.get(0);
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAMETER_ERROR.getCode(), fieldError.getDefaultMessage());
            }
        }
        return ResponseResult.okResult();
    }

}
@PostMapping("/add")
    public  ResponseResult saveUser(@RequestBody @Valid User user) {
        userService.save(user);

        return ResponseResult.okResult();

    }

上述代码是一个全局异常处理器,用于捕获系统运行时抛出的异常,并返回统一的错误信息。这个异常处理器使用了 Spring 框架的@RestControllerAdvice 注解,表示这是一个全局的异常处理器,会对整个系统中的异常进行统一处理。同时,这个类还使用了 Lombok 的@Slf4j 注解,方便进行日志打印。

异常处理器中定义了三个异常处理方法,分别处理 SystemException、Exception 和 MethodArgumentNotValidException 三种异常。

其中,@ExceptionHandler 注解用于指定处理的异常类型,而@ResponseStatus 注解用于设置 HTTP 响应状态码。

在 UserController 中,@Valid 注解用于开启参数校验功能,表示对请求参数进行校验。如果请求参数不符合要求,则会抛出 MethodArgumentNotValidException 异常。注意到在 GlobalExceptionHandler 中已经定义了对这种异常的处理方法,所以这个异常不会被@Valid 注解捕获,而是会被全局异常处理器捕获并处理。