SpringBoot は、エレガントでグローバルに統合された Restful API 応答フレームワークを定義します 3

ここまでグローバルレスポンスも含めて設計しており、異常エラーレスポンスは一律に返すようになっている。ただし、私たちが設計したエラーの内容は比較的あいまいで統一されており、改良することもできるため、エラーの特定が容易になります。

Web 上でもモバイル上でも、HTTP インターフェイスを呼び出す必要がある場合、パラメーターの欠落、型エラー、システム エラーなど、さまざまなエラーが発生する可能性があります。エラー情報の戻り値を標準化するには、統一インターフェイスのエラー戻り値を定義する必要があります。インターフェイス エラーの戻り値の統一された設計を通じて、呼び出し元によるさまざまなエラーの処理を標準化し、より詳細で正確なエラー プロンプトを提供し、バックエンドがインターフェイスの戻り値の標準化された設計を実現できるようにします。したがって、インターフェースのエラー戻り値の設計は、エラー情報の標準化された処理だけでなく、ビジネスエラーの設計も含みます。このような設計により、インターフェイスの効率と保守性が効果的に向上します。

エラーコードの定義

http statsエラーに応じて、通常は次のカテゴリに分類できます

  1. 200: リクエストは成功しました
  2. 400: リクエストパラメータエラー
  3. 401: 不正アクセス
  4. 403: リソースへのアクセスが禁止されていることを示します。
  5. 404: リソースが見つからなかったことを示します。
  6. 500: 内部サーバーエラーを示します。

エラーコードの設計には、httpエラーコード+3桁のAPIカスタムエラーコードの合計6桁を使用でき、具体的には各モジュールが何を表すかを独自のビジネスロジックに合わせて定義できます。 、数字はさまざまなモジュールに対応します

対応するエラー形式は次のとおりです。

エラーインターフェイス

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();
}

カスタムエラー実装の列挙

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;
    }


}

グローバル例外エラー処理

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());
    }

}

特定のプロジェクト コードは github に同期されており、一連の統合スキャフォールディング ツールは将来的に改良および更新され、すぐに使用できるようになります。

おすすめ

転載: blog.csdn.net/u011738045/article/details/130491967