SpringBoot defines an elegant global unified Restful API response framework three

We have designed it so far, including the global response, and the abnormal error response is returned uniformly. However, the error content we designed is relatively vague and unified, and it can also be refined, which is more conducive to locating errors

When we need to call the Http interface, whether it is on the web or mobile, we may encounter various errors, such as missing parameters, type errors, system errors, etc. In order to standardize the return of error information, we need to define a unified interface error return value. Through the unified design of the interface error return value, we can standardize the caller's handling of various errors, provide more detailed and accurate error prompts, and help the backend realize the standardized design of the interface return value. Therefore, the design of the error return value of the interface is not only the standardized processing of error information, but also involves the design of business errors. Such a design can effectively improve the efficiency and maintainability of the interface.

Error code definition

According to http statsthe error can usually be divided into the following categories

  1. 200: The request was successful
  2. 400: Request parameter error
  3. 401: Unauthorized Access
  4. 403: Indicates that access to the resource is forbidden.
  5. 404: Indicates that the resource was not found.
  6. 500: Indicates an internal server error.

For the design of the error code, you can use the http error code + three-digit api custom error code, which is a total of 6 digits. Specifically, what each module represents can be defined according to your own business logic. Different numbers, the digits correspond to different modules

The corresponding error format is as follows

error interface

package cn.soboys.springbootrestfulapi.common.error;

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/5/2 21:33
 * @webSite https://github.com/coder-amiao
 * 错误码接口,凡各模块错误码枚举类,皆须为此接口的子类型
 */
public interface ErrorCode {
    Integer getCode();

    String getMessage();

    boolean getSuccess();
}

Custom error implementation enumeration

package cn.soboys.springbootrestfulapi.common.error;

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/5/2 21:36
 * @webSite https://github.com/coder-amiao
 */
public enum CommonErrorCode implements ErrorCode {

    NOT_FOUND(false, 404, "接口不存在"),
    FORBIDDEN(false, 403, "资源拒绝访问"),
    UNAUTHORIZED(false, 401, "未认证(签名错误)"),
    INTERNAL_SERVER_ERROR(false, 500, "服务网络不可用"),
    PARAM_ERROR(false, 110001, "参数错误");



    CommonErrorCode(Boolean success, Integer code, String message) {
        this.success = success;
        this.code = code;
        this.message = message;

    }

    /**
     * 响应是否成功
     */
    private Boolean success;
    /**
     * 响应状态码
     */
    private Integer code;
    /**
     * 响应信息
     */
    private String message;


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

    @Override
    public String getMessage() {
        return message;
    }

    @Override
    public boolean getSuccess() {
        return success;
    }


}

Global exception error handling

package cn.soboys.springbootrestfulapi.common.exception;


import cn.hutool.core.collection.CollectionUtil;
import cn.soboys.springbootrestfulapi.common.error.CommonErrorCode;
import cn.soboys.springbootrestfulapi.common.resp.R;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/4/29 00:21
 * @webSite https://github.com/coder-amiao
 * 统一异常处理器
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 通用异常处理方法
     **/
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public R error(Exception e, WebRequest request) {
        e.printStackTrace();
        return R.setResult(CommonErrorCode.INTERNAL_SERVER_ERROR)
                .request(request.getDescription(true))
                .errorMsg(e.getMessage());
    }



    /**
     * 处理 form data方式调用接口对象参数校验失败抛出的异常
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public R BindExceptionHandler(BindException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        return R.failure().code(CommonErrorCode.PARAM_ERROR.getCode()).message(message);
    }

    /**
     * 处理Get请求中 验证路径中 单个参数请求失败抛出异常
     * @param e
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public R ConstraintViolationExceptionHandler(ConstraintViolationException e) {
        String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
        return R.failure().code(CommonErrorCode.PARAM_ERROR.getCode()).message(message);
    }


    /**
     * 处理 json 请求体调用接口对象参数校验失败抛出的异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R jsonParamsException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        String msg=";";

        for (FieldError fieldError : bindingResult.getFieldErrors()) {
             msg = String.format("%s%s;", fieldError.getField(), fieldError.getDefaultMessage())+msg;
        }
        return R.failure().code(CommonErrorCode.PARAM_ERROR.getCode()).message(msg);
    }

    /**
     * 自定义异常处理方法
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public R error(BusinessException e) {
        e.printStackTrace();
        return R.failure().message(e.getMessage()).code(e.getCode());
    }

}

The specific project code has been synchronized to github, and a series of integrated scaffolding tools will be improved and updated in the future, which can be used out of the box

Guess you like

Origin blog.csdn.net/u011738045/article/details/130491967