首页 > 其他分享 >SpringBoot定义优雅全局统一Restful API 响应框架三

SpringBoot定义优雅全局统一Restful API 响应框架三

时间:2023-05-04 17:55:52浏览次数:48  
标签:code return SpringBoot 错误 API import message Restful public

我们目前已经设计出了,包含全局响应,异常错误响应进行了统一返回。但是错误内容我们设计的比较模糊统一,还可以进行细化这样更有利于定位错误

当我们需要调用Http接口时,无论是在Web端还是移动端,都有可能遇到各种错误,例如参数缺失、类型错误、系统错误等。为了规范错误信息的返回,我们需要定义一个统一的接口错误返回值。通过对接口错误返回值的统一设计,我们可以规范调用方对各种不同错误的处理方式,并提供更加详细、准确的错误提示,同时也帮助后端实现接口返回值的规范化设计。因此,接口错误返回值的设计不仅仅是对错误信息的规范化处理,还涉及到业务上的错误设计。这样的设计可以有效地提高接口的使用效率和可维护性。

错误码定义

根据 http stats 错误通常可以分为以下几大类

  1. 200:请求成功
  2. 400:请求参数错误
  3. 401:未授权访问
  4. 403:表示禁止访问资源。
  5. 404:表示未找到资源。
  6. 500:表示服务器内部错误。

错误码的设计,可以借用http错误码+三位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 上,后续会完善更新一系列整合脚手架工具,能够开箱即用

标签:code,return,SpringBoot,错误,API,import,message,Restful,public
From: https://www.cnblogs.com/kenx/p/17372062.html

相关文章

  • C++获取阿里巴巴1688中国站店铺详情 API 接口返回值示例说明
    ​C++(cplusplus)是一种计算机高级程序设计语言,由C语言扩展升级而产生,最早于1979年由本贾尼·斯特劳斯特卢普在AT&T贝尔工作室研发。C++既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。......
  • springboot与mongodb之事务管理(二)
    一、事务说明1、在4.0版本中,MongoDB支持副本集上的多文档事务,分片集群是不支持事务的,会报以下异常TransactionsarenotsupportedbytheMongoDBclustertowhichthisclientisconnected2、在版本4.2中,MongoDB引入了分布式事务,在副本集或分片集群上都是支持事务的。3......
  • springboot单元测试中添加了@Autowired任然报错nullpoint(已解决)
     使用了autowired还是报错空指针异常说明就是包没有导入,springboot导包的操作在于启动application类,所以问题就在于没有单元测试时没有启动主类,解决方法:@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes=SaTokenDemoApplication.class)加上如上的注解,@runwi......
  • 【SpringBoot】【一】 加载初始化器、监听器详解
    1 前言本节主要讲下SpringBoot启动的时候,加载初始化器、监听器的过程哈。2 加载时机我们先来看下加载的时机,也就是什么时候加载的呢,就是我们SpringBoot启动的时候,创建SpringApplication的时候就会去加载的,我们看下:@SpringBootApplicationpublicclassDemoApplicati......
  • springboot与mongodb之整合(一)
    一、添加maven依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId><version>2.6.7</version></dependency>二、配置properties文件1、mongodb无......
  • springboot 切面注解方式 记录日志
    1.定义GateOpLogimportjava.lang.annotation.*;/***操作日志记录*@authorcodefulture*/@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceGateOpLog{/***说明*/Strin......
  • PKUSC & GDCPC & APIO 2023 游记
    离得太近,游记打算扔一起。有没有神仙面基啊/kel。PKUSC2023Day-?突然听说不给NOILinux,震惊。后来确认了这个传言,紧急下载了红色的(?)Devc++开始用。Day-2/-1用windows打模拟好痛苦,怎么回事呢。不会多项式。不会字符串。我要坚信他不考。该打点什么板子呢(?GDCPCDa......
  • 用手机号码归属地 API 开发的应用推荐
    引言手机号码归属地API是一种提供手机号码归属地信息的接口,通过该接口,可以获取手机号码所属的省份、城市、运营商等信息。它可以帮助企业更好地了解客户,为个性化推荐和精准广告投放提供数据支持。作为一种数据服务,手机号码归属地API在电商、金融、社交、广告等领域得到广泛应用......
  • springboot异常处理的通用方式2
    2、定义一个异常的枚举数组•ServerErrCodeDefine类//```java@AllArgsConstructor@GetterpublicenumServerErrCodeDefine{privateinterrCode;privateStringcode;privateHttpStatushttpStatus;privateStringmessageSourceKey;/***************************......
  • 天气预报查询 API 提供个性化的天气服务的设计思路
    引言假设你是一个开发人员或公司,正在考虑开发一款天气应用程序,但你意识到市场上已经有很多竞争者在使用天气预报查询API来提供类似的服务,本文将一起探寻一些创新的方法来提高应用程序的竞争力。扩大竞争力的一些建议如果市面上已经有很多使用天气预报查询API的应用,您可以通......