最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot封裝響應(yīng)處理超詳細(xì)講解

 更新時(shí)間:2022年12月23日 14:39:04   作者:ζ荷逸こ  
這篇文章主要介紹了SpringBoot封裝響應(yīng)處理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

背景

越來越多的項(xiàng)目開始基于前后端分離的模式進(jìn)行開發(fā),這對(duì)后端接口的報(bào)文格式便有了一定的要求。通常,我們會(huì)采用JSON格式作為前后端交換數(shù)據(jù)格式,從而減少溝通成本等。

報(bào)文基本格式

一般報(bào)文格式通常會(huì)包含狀態(tài)碼、狀態(tài)描述(或錯(cuò)誤提示信息)、業(yè)務(wù)數(shù)據(jù)等信息。 在此基礎(chǔ)上,不同的架構(gòu)師、項(xiàng)目搭建者可能會(huì)有所調(diào)整。 但從整體上來說,基本上都是大同小異。

在SpringBoot項(xiàng)目中,通常接口返回的報(bào)文中至少包含三個(gè)屬性:

code:請(qǐng)求接口的返回碼,成功或者異常等返回編碼,例如定義請(qǐng)求成功。

message:請(qǐng)求接口的描述,也就是對(duì)返回編碼的描述。

data:請(qǐng)求接口成功,返回的業(yè)務(wù)數(shù)據(jù)。

示例報(bào)文如下:

{
  "code":200,
  "message":"SUCCESS",
  "data":{
   "info":"測(cè)試成功"
  }
}

在上述報(bào)文格式中,不同的設(shè)計(jì)者是會(huì)有一些分歧的,特別是code值的定義。如果完全基于RESTful API設(shè)計(jì)的話,code字段可能就不需要存在了,而是通過HTTP協(xié)議中提供的GET、POST、PUT、DELETE操作等來完成資源的訪問。

但在實(shí)踐中,不論是出于目前國(guó)內(nèi)大多數(shù)程序員的習(xí)慣,還是受限于HTTP協(xié)議提供的操作方法的局限性,很少完全遵照RESTful API方式進(jìn)行設(shè)計(jì)。通常都是通過自定義Code值的形式來賦予它業(yè)務(wù)意義或業(yè)務(wù)錯(cuò)誤編碼。

雖然可以不用完全遵守RESTful API風(fēng)格來定義Code,在Code值的自定義中,也存在兩種形式:遵循HTTP狀態(tài)碼和自主定義。

像上面的示例,用200表示返回成功,這就是遵循HTTP響應(yīng)狀態(tài)碼的形式來返回,比如還有其他的400、401、404、500等。當(dāng)然,還有完全自主定義的,比如用0表示成功,1表示失敗,然后再跟進(jìn)通用編碼、業(yè)務(wù)分類編碼等進(jìn)行定義。

在此,筆者暫不評(píng)論每種形式的好壞,只列舉了常規(guī)的幾種形式,大家了解對(duì)應(yīng)的情況,做到心中有數(shù),有所選擇即可。

創(chuàng)建枚舉類

用于定義返回的錯(cuò)誤碼:

public enum ErrorCode {
    SUCCESS(0, "ok", ""),
    FAIL(500, "failed",""),
    PARAMS_ERROR(40000, "請(qǐng)求參數(shù)錯(cuò)誤", ""),
    NULL_ERROR(40001, "請(qǐng)求數(shù)據(jù)為空", ""),
    NOT_LOGIN(40100, "未登錄", ""),
    NO_AUTH(40101, "無權(quán)限", ""),
    SYSTEM_ERROR(50000, "系統(tǒng)內(nèi)部異常", "");
    private final int code;
    /**
     * 狀態(tài)碼信息
     */
    private final String message;
    /**
     * 狀態(tài)碼描述(詳情)
     */
    private final String description;
    ErrorCode(int code, String message, String description) {
        this.code = code;
        this.message = message;
        this.description = description;
    }
    public int getCode() {
        return code;
    }
    public String getMessage() {
        return message;
    }
    public String getDescription() {
        return description;
    }
}

定義統(tǒng)一返回結(jié)果實(shí)體類

@Data
public class BaseResponse<T> implements Serializable {
    private int code;
    private T data;
    private String message;
    private String description;
    public BaseResponse(int code, T data, String message, String description) {
        this.code = code;
        this.data = data;
        this.message = message;
        this.description = description;
    }
    public BaseResponse(int code, T data, String message) {
        this(code, data, message, "");
    }
    public BaseResponse(int code, T data) {
        this(code, data, "", "");
    }
    public BaseResponse(ErrorCode errorCode) {
        this(errorCode.getCode(), null, errorCode.getMessage(), errorCode.getDescription());
    }
}

在BaseResponse中運(yùn) 用了泛型和公共方法、構(gòu)造方法的封裝,方便在業(yè)務(wù)中使用。 示例中只提供了部分方法的封裝,根據(jù)自身業(yè)務(wù)場(chǎng)景和需要可進(jìn)一步封裝。

定義返回工具類

public class ResultUtils {
    /**
     * 成功
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> success(T data) {
        return new BaseResponse<>(ErrorCode.SUCCESS.getCode(), data, "ok");
    }
    public static <T> BaseResponse<T> success(String message) {
        return new BaseResponse<>(ErrorCode.SUCCESS.getCode(), null, message);
    }
    /**
     * 失敗
     *
     * @param errorCode
     * @return
     */
    public static BaseResponse error(ErrorCode errorCode) {
        return new BaseResponse<>(errorCode);
    }
    /**
     * 失敗
     *
     * @param code
     * @param message
     * @param description
     * @return
     */
    public static BaseResponse error(int code, String message, String description) {
        return new BaseResponse(code, null, message, description);
    }
    /**
     * 失敗
     *
     * @param errorCode
     * @return
     */
    public static BaseResponse error(ErrorCode errorCode, String message, String description) {
        return new BaseResponse(errorCode.getCode(), null, message, description);
    }
    /**
     * 失敗
     *
     * @param errorCode
     * @return
     */
    public static BaseResponse error(ErrorCode errorCode, String description) {
        return new BaseResponse(errorCode.getCode(), errorCode.getMessage(), description);
    }
    public static BaseResponse error(String message) {
        return new BaseResponse(ErrorCode.FAIL.getCode(),message);
    }
    /**
     * 失敗
     *
     * @param errorCode
     * @return
     */
    public static BaseResponse error(HttpStatus errorCode, String description) {
        return new BaseResponse(errorCode.value(), errorCode.getReasonPhrase(), description);
    }
}

統(tǒng)一報(bào)文封裝在接口中的使用

@RestController
public class TestController {
  @RequestMapping("/calc")
  public ResponseInfo<String> calc(Integer id) {
    try {
      // 模擬異常業(yè)務(wù)代碼
      int num = 1 / id;
      log.info("計(jì)算結(jié)果num={}", num);
      return ResultUtils.success();
    } catch (Exception e) {
      return ResponseInfo.error("系統(tǒng)異常,請(qǐng)聯(lián)系管理員!");
    }
  }
}

統(tǒng)一異常處理

在上述實(shí)例中,我們通過try…catch的形式捕獲異常,并進(jìn)行處理。 在SpringBoot中,我們可以通過RestControllerAdvice注解來定義全局異常處理,這樣就無需每處都try…catch了。

/**
 * 全局異常處理器
 *
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    @ExceptionHandler(BusinessException.class)
    public BaseResponse businessExceptionHandler(BusinessException e) {
        log.error("businessException: " + e.getMessage(), e);
        return ResultUtils.error(e.getCode(), e.getMessage(), e.getDescription());
    }
    @ExceptionHandler(RuntimeException.class)
    public BaseResponse runtimeExceptionHandler(RuntimeException e) {
        log.error("runtimeException", e);
        return ResultUtils.error(ErrorCode.SYSTEM_ERROR, e.getMessage(), "");
    }
    /**
     * 參數(shù)格式異常處理
     */
    @ExceptionHandler({IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public BaseResponse badRequestException(IllegalArgumentException ex) {
        log.error("參數(shù)格式不合法:{}", ex.getMessage());
        return ResultUtils.error(HttpStatus.BAD_REQUEST, "參數(shù)格式不符!");
    }
    /**
     * 權(quán)限不足異常處理
     */
    @ExceptionHandler({AccessDeniedException.class})
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public BaseResponse badRequestException(AccessDeniedException ex) {
        return ResultUtils.error(HttpStatus.FORBIDDEN, ex.getMessage());
    }
    /**
     * 參數(shù)缺失異常處理
     */
    @ExceptionHandler({MissingServletRequestParameterException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public BaseResponse badRequestException(Exception ex) {
        return ResultUtils.error(HttpStatus.BAD_REQUEST, "缺少必填參數(shù)!");
    }
    /**
     * 空指針異常
     */
    @ExceptionHandler(NullPointerException.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public BaseResponse handleTypeMismatchException(NullPointerException ex) {
        log.error("空指針異常,{}", ex.getMessage());
        return ResultUtils.error("空指針異常");
    }
    @ExceptionHandler(Exception.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public BaseResponse handleUnexpectedServer(Exception ex) {
        log.error("系統(tǒng)異常:", ex);
        return ResultUtils.error("系統(tǒng)發(fā)生異常,請(qǐng)聯(lián)系管理員");
    }
    /**
     * 系統(tǒng)異常處理
     */
    @ExceptionHandler(Throwable.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public BaseResponse exception(Throwable throwable) {
        log.error("系統(tǒng)異常", throwable);
        return ResultUtils.error(HttpStatus.INTERNAL_SERVER_ERROR, "系統(tǒng)異常,請(qǐng)聯(lián)系管理員!");
    }
}

在上述方法中,對(duì)一些常見的異常進(jìn)行了統(tǒng)一處理。 通常情況下,根據(jù)業(yè)務(wù)需要還會(huì)定義業(yè)務(wù)異常,并對(duì)業(yè)務(wù)異常進(jìn)行處理,大家可以根據(jù)自己項(xiàng)目中異常的使用情況進(jìn)行拓展。

關(guān)于@RestControllerAdvice的幾點(diǎn)說明:

@RestControllerAdvice注解包含了@Component注解,會(huì)把被注解的類作為組件交給Spring來管理。

@RestControllerAdvice注解包含了@ResponseBody注解,異常處理完之后給調(diào)用方輸出一個(gè)JSON格式的封裝數(shù)據(jù)。

@RestControllerAdvice注解有一個(gè)basePackages屬性,該屬性用來攔截哪個(gè)包中的異常信息,一般不指定,攔截項(xiàng)目工程中的所有異常。

在方法上通過@ExceptionHandler注解來指定具體的異常,在方法中處理該異常信息,最后將結(jié)果通過統(tǒng)一的JSON結(jié)構(gòu)體返回給調(diào)用者。

重構(gòu)接口

@RestController
public class TestController {
  @RequestMapping("/calc")
  public ResponseInfo<String> calc(Integer id) {
         // 模擬異常業(yè)務(wù)代碼
      int num = 1 / id;
      log.info("計(jì)算結(jié)果num={}", num);
      return ResultUtils.success();
     }
}

在請(qǐng)求的時(shí)候,不傳遞id值,即在瀏覽器中訪問:

{
  "code": 500,
  "data": "空指針異常",
  "message": "",
  "description": ""
}

可以看到統(tǒng)一異常處理對(duì)空指針異常進(jìn)行了攔截處理,并返回了ExceptionHandlerAdvice中定義的統(tǒng)一報(bào)文格式。

小結(jié)

在使用SpringBoot或其他項(xiàng)目中,統(tǒng)一的報(bào)文格式和統(tǒng)一的異常處理都是必須的。 本篇文章介紹了基于SpringBoot的實(shí)現(xiàn),如果你的項(xiàng)目中采用了其他的技術(shù)棧,則可考慮對(duì)應(yīng)的處理方式。 同時(shí),日常中很多類似的功能都可以統(tǒng)一進(jìn)行處理,避免大量無效的硬編碼。

到此這篇關(guān)于SpringBoot封裝響應(yīng)處理超詳細(xì)講解的文章就介紹到這了,更多相關(guān)SpringBoot封裝響應(yīng)處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java從控制臺(tái)接收一個(gè)數(shù)字的實(shí)例詳解

    java從控制臺(tái)接收一個(gè)數(shù)字的實(shí)例詳解

    這篇文章主要介紹了java從控制臺(tái)接收一個(gè)數(shù)字的實(shí)例詳解的相關(guān)資料,這里提供實(shí)例代碼,注釋說明清晰,需要的朋友可以參考下
    2017-07-07
  • springboot中設(shè)置定時(shí)任務(wù)的三種方法小結(jié)

    springboot中設(shè)置定時(shí)任務(wù)的三種方法小結(jié)

    在我們開發(fā)項(xiàng)目過程中,經(jīng)常需要定時(shí)任務(wù)來幫助我們來做一些內(nèi)容,本文介紹了springboot中設(shè)置定時(shí)任務(wù)的三種方法,主要包括@Scheduled注解,Quartz框架和xxl-job框架的實(shí)現(xiàn),感興趣的可以了解一下
    2023-12-12
  • 解決Spring session(redis存儲(chǔ)方式)監(jiān)聽導(dǎo)致創(chuàng)建大量redisMessageListenerContailner-X線程問題

    解決Spring session(redis存儲(chǔ)方式)監(jiān)聽導(dǎo)致創(chuàng)建大量redisMessageListenerConta

    這篇文章主要介紹了解決Spring session(redis存儲(chǔ)方式)監(jiān)聽導(dǎo)致創(chuàng)建大量redisMessageListenerContailner-X線程問題,需要的朋友可以參考下
    2018-08-08
  • springboot中的pom文件?project報(bào)錯(cuò)問題

    springboot中的pom文件?project報(bào)錯(cuò)問題

    這篇文章主要介紹了springboot中的pom文件?project報(bào)錯(cuò)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 簡(jiǎn)單理解Java的抽象類

    簡(jiǎn)單理解Java的抽象類

    這篇文章主要介紹了Java的抽象類,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • Maven鏡像地址配置示例大全

    Maven鏡像地址配置示例大全

    這篇文章主要介紹了Maven鏡像地址配置示例大全,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2020-06-06
  • Java實(shí)戰(zhàn)個(gè)人博客系統(tǒng)的實(shí)現(xiàn)流程

    Java實(shí)戰(zhàn)個(gè)人博客系統(tǒng)的實(shí)現(xiàn)流程

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+springboot+mybatis+redis+vue+elementui+Mysql實(shí)現(xiàn)一個(gè)個(gè)人博客系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平
    2022-01-01
  • mybatis-plus 查詢時(shí)排除字段方法的兩種方法

    mybatis-plus 查詢時(shí)排除字段方法的兩種方法

    我們?cè)陂_發(fā)應(yīng)用時(shí),在某些應(yīng)用場(chǎng)景下查詢有時(shí)需要排除某些字段,本文主要介紹了兩種方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • java 數(shù)據(jù)類型有哪些取值范圍多少

    java 數(shù)據(jù)類型有哪些取值范圍多少

    這篇文章主要介紹了java 數(shù)據(jù)類型有哪些取值范圍多少的相關(guān)資料,網(wǎng)上關(guān)于java 數(shù)據(jù)類型的資料有很多,不夠全面,這里就整理下,需要的朋友可以參考下
    2017-01-01
  • Java數(shù)組的運(yùn)用詳解

    Java數(shù)組的運(yùn)用詳解

    這篇文章主要給大家介紹了關(guān)于Java中數(shù)組的定義和使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08

最新評(píng)論

和龙市| 商都县| 镇江市| 桐庐县| 高安市| 彭阳县| 易门县| 颍上县| 宾川县| 来安县| 措勤县| 达孜县| 三明市| 神农架林区| 越西县| 石家庄市| 镇安县| 桓台县| 蓝山县| 永州市| 沈丘县| 南靖县| 商都县| 凤城市| 安顺市| 慈利县| 汝南县| 慈溪市| 湘西| 福海县| 兰西县| 梓潼县| 繁峙县| 临漳县| 鄂州市| 宁晋县| 应城市| 独山县| 福海县| 奈曼旗| 黄梅县|