91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot怎么封裝統一響應體

發布時間:2021-05-25 13:54:36 來源:億速云 閱讀:439 作者:小新 欄目:開發技術

這篇文章主要介紹了SpringBoot怎么封裝統一響應體,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

一、前言

關于統一響應體的封裝,沒有一個標準答案,我在各種技術社區看了一遍,匯總了一個復用性比較好的方案。

二、添加結果類枚舉

在項目目錄下面建一個 responseEntity 的 package,然后在里面建一個 ResultEnum 枚舉類,添加如下代碼:

SpringBoot怎么封裝統一響應體

這邊介紹一下枚舉類的用法。枚舉類的作用實際上就是定義常量,如果不使用枚舉類,通常采用靜態常量來表示:

public static final Integer OK_CODE = 200;
public static final String OK_MESSAGE = "成功";
public static final Integer BAD_REQUEST_CODE = 400;
public static final String BAD_REQUEST_MESSAGE = "參數錯誤";

這樣的話存在一些問題,一是字段表意不明,特別是看別人的代碼時,會很懵逼;第二當業務規模增大之后,可能要維護成百上千的靜態常量,如果都寫在一個文件里面,容易造成命名混淆,閱讀也比較麻煩。

然后使用枚舉類定義常量就比較方便,相當于一個接口,使用時只需要封裝內部的數據類型,并且限定數據域。而且對于不同的枚舉變量,可以調用不同的處理方法(實現枚舉類的抽象方法可以做到這一點)。關于枚舉類的一些知識點匯總如下:

  • 使用enum定義的枚舉類默認繼承了java.lang.Enum,實現了java.lang.Comparable接口,且不能繼承其他類,也不可以被繼承。但枚舉類可以實現一個或多個接口;

  • 枚舉類的所有實例必須放在第一行顯示,不需使用new,不需顯示調用構造方法,每個變量都是public static final修飾的,最終以分號結束。在之后的反編譯中,我們就可以理解枚舉類其實也是顆語法糖;

  • 枚舉類的構造方法是私有的,默認的就是 private,所以不用再添加 private;

枚舉類內部常用的方法:

  • valueOf() :返回當前枚舉類的name屬性,如果沒有,則throw new java.lang.IllegalArgumentException();

  • values() :是編譯器自動生成的方法,Enum中并沒有該方法,返回包括所有枚舉變量的數組;

  • toString()name() :兩個方法一樣,返回當前枚舉類變量的name屬性,如果覺得不夠用,可以覆蓋默認的 toString ,結合 SWITCH CASE 來靈活的實現 toString() 方法;

  • ordinal() :枚舉類會給所有的枚舉變量一個默認的次序,該次序從0開始,是根據我們定義的次序來排序的。而ordinal()方法就是獲取這個次序(或者說下標);

  • compareTo() :比較的是兩個枚舉變量的次序,返回兩個次序相減后的結果;

定義了枚舉類之后,在類的上面添加 lombok 的 @Getter 注解,給對象的每個屬性添加 getter 方法,方便后面獲取常量。例如要獲取 OK 的狀態碼,就可以這樣寫:

ResultEnum.OK.getCode()

這邊再解釋下 @Data@Getter@Setter 的區別:

  • @Data:注解在類上;提供類所有屬性的 getter 和 setter 方法,此外還提供了equals、canEqual、hashCode、toString 方

  • @Getter:注解在屬性上:為屬性提供 getter 方法;注解再類上表示當前類中所有屬性都生成getter方法

  • @Setter:注解在屬性上:為屬性提供 setter 方法;注解再類上表示當前類中所有屬性都生成setter方法

三、添加統一結果類

還是在 responseEntity 目錄下面,建一個 ServerResponse 類,添加如下代碼:

@Data
public class ServerResponse {
	private Boolean success;
    private Integer code;
    private String message;
    private Object data;

	// 構造方法設為私有
    private ServerResponse() {}

	public static ServerResponse ok(Object params) {
        ServerResponse serverResponse = new ServerResponse();
        serverResponse.setSuccess(ResultEnum.OK.getSuccess());
        serverResponse.setCode(ResultEnum.OK.getCode());
        serverResponse.setMessage(ResultEnum.OK.getMessage()); // 成功展示默認提示信息
        serverResponse.setData(params); // 返回傳入的參數
        return serverResponse;
    }

	public static ServerResponse badRequest(@Nullable String message) {
        ServerResponse serverResponse = new ServerResponse();
        serverResponse.setSuccess(ResultEnum.BAD_REQUEST.getSuccess());
        serverResponse.setCode(ResultEnum.BAD_REQUEST.getCode());
        serverResponse.setMessage(message != null ? message : ResultEnum.BAD_REQUEST.getMessage()); // 校驗失敗傳入指定的提示信息
        serverResponse.setData(null); // 校驗失敗不返回參數
        return serverResponse;
    }
}

在上面的代碼中,成員變量和構造方法都是私有的,只有靜態方法向外暴露。然后處理成功的方法,message 展示默認提示信息,即定義在枚舉類里面的常量,data 是需要傳給前端的 JSON 參數;處理參數錯誤的方法,message 展示傳進去的錯誤信息,如果傳的是 null ,則展示默認提示信息,即定義在枚舉類里面的常量,data 是傳給前端的參數,但是在參數錯誤的情況下就不需要傳了,因此是 null

這邊有一個問題,暫時不清楚 Java 是否支持函數參數可選,本人測試發現定義函數的時候有參數,但是調用的時候不傳,IDE 會給錯誤提示,因此這里通過傳 null 來解決

四、控制層返回

在定義了統一結果類之后,就可以在接口中使用了。還是用之前那個方法,通過 POST 請求獲取用戶信息,再原封不動返回過去:

@PostMapping("validateUser")
public ServerResponse userValidate(@RequestBody @Validated UserDTO userDTO) {
    return ServerResponse.ok(null);
}

這邊先給參數傳 null ,不給前端進行返回,看一下響應的結果:

SpringBoot怎么封裝統一響應體

然后傳遞參數:

@PostMapping("validateUser")
public ServerResponse userValidate(@RequestBody @Validated UserDTO userDTO) {
    return ServerResponse.ok(userDTO);
}

看一下響應的結果:

SpringBoot怎么封裝統一響應體

五、異常處理類使用統一響應體

然后我們給異常處理的方法也添加統一響應體:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ServerResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        // 注意傳進去的表達式有可能是 null
        // 因此在 ServerResponse 對 message 是否為 null 進行了判斷
        // 如果是 null 就展示默認的提示內容
        return ServerResponse.badRequest(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
    }

    // 其他異常處理方法
}

然后我們模擬一下參數異常的情況:

SpringBoot怎么封裝統一響應體

這樣看起來是正常了,但是存在一個問題,后端判斷參數異常的時候,因為我們捕獲了異常,所以返回給前端的狀態碼還是 200 ,如何讓狀態碼改為 400 呢?在 SpringBoot 中指定 HTTP 狀態碼主要有三種方式:

  • HttpServletResponse

  • @ResponseStatus

  • ResponseEntity

這邊使用第三種方式,具體的用法看一下代碼應該就明白了。我們把剛才統一結果類的方法修改下:

public static ResponseEntity<ServerResponse> badRequest(@Nullable String message) {
	ServerResponse serverResponse = new ServerResponse();
    serverResponse.setSuccess(ResultEnum.BAD_REQUEST.getSuccess());
    serverResponse.setCode(ResultEnum.BAD_REQUEST.getCode());
    serverResponse.setMessage(message != null ? message : ResultEnum.BAD_REQUEST.getMessage()); // 校驗失敗傳入指定的提示信息
    serverResponse.setData(null); // 校驗失敗不返回參數
    return new ResponseEntity<>(serverResponse, HttpStatus.BAD_REQUEST); // 使用 ResponseEntity 對象設置響應狀態碼
}

可以看到我們用一個 ResponseEntity 對象包裹了我們封裝的響應體,然后返回了這個對象。其中第二個參數就是狀態碼,HttpStatus.BAD_REQUEST 就代表 400 。然后我們還要修改下異常處理類的返回類型:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseEntity<ServerResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        return ServerResponse.badRequest(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
    }

    // 其他異常處理方法
}

再來調試一下,這下狀態碼正常了:

SpringBoot怎么封裝統一響應體

在統一結果類中所有的方法都根據上面的示例進行修改即可,我這邊添加了幾個方法,給各位參考下,具體可以根據業務場景進行添加:

@Data
public class ServerResponse {
    private Boolean success;
    private Integer code;
    private String message;
    private Object data;

    // 構造方法設為私有
    private ServerResponse() {}

    /**
     * 200 請求成功
     * @param params 傳給前端的參數
     * @return ResponseEntity<ServerResponse>
     */
    public static ResponseEntity<ServerResponse> ok(Object params) {
        ServerResponse serverResponse = new ServerResponse();
        serverResponse.setSuccess(ResultEnum.OK.getSuccess());
        serverResponse.setCode(ResultEnum.OK.getCode());
        serverResponse.setMessage(ResultEnum.OK.getMessage()); // 成功展示默認提示信息
        serverResponse.setData(params); // 返回傳入的參數
        return new ResponseEntity<>(serverResponse, HttpStatus.OK);
    }

    /**
     * 201 創建成功
     * @return ResponseEntity<ServerResponse>
     */
    public static ResponseEntity<ServerResponse> created() {
        ServerResponse serverResponse = new ServerResponse();
        serverResponse.setSuccess(ResultEnum.CREATED.getSuccess());
        serverResponse.setCode(ResultEnum.CREATED.getCode());
        serverResponse.setMessage(ResultEnum.CREATED.getMessage());
//        serverResponse.setData(null);
        return new ResponseEntity<>(serverResponse, HttpStatus.CREATED);
    }

    /**
     * 204 請求成功,沒有響應體
     * @return ResponseEntity<ServerResponse>
     */
    public static ResponseEntity<ServerResponse> noContent() {
        return new ResponseEntity<>(null, HttpStatus.NO_CONTENT);
    }

    /**
     * 400 參數錯誤
     * @param message 自定義錯誤信息
     * @return ResponseEntity<ServerResponse>
     */
    public static ResponseEntity<ServerResponse> badRequest(@Nullable String message) {
        ServerResponse serverResponse = new ServerResponse();
        serverResponse.setSuccess(ResultEnum.BAD_REQUEST.getSuccess());
        serverResponse.setCode(ResultEnum.BAD_REQUEST.getCode());
        serverResponse.setMessage(message != null ? message : ResultEnum.BAD_REQUEST.getMessage()); // 校驗失敗傳入指定的提示信息
//        serverResponse.setData(null); // 校驗失敗不返回參數
        return new ResponseEntity<>(serverResponse, HttpStatus.BAD_REQUEST); // 使用 ResponseEntity 對象設置響應狀態碼
    }
}

此外,@ResponseStatus 也是一種設置狀態碼常用的方法,只需要在 Controller 方法中加一個注解就可以:

@PostMapping("validateUser")
@ResponseStatus(code=HttpStatus.BAD_REQUEST, reason="參數異常")
public ServerResponse userValidate(@RequestBody @Validated UserDTO userDTO) {
    return ServerResponse.ok(userDTO);
}

springboot是什么

springboot一種全新的編程規范,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程,SpringBoot也是一個服務于框架的框架,服務范圍是簡化配置文件。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“SpringBoot怎么封裝統一響應體”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

保德县| 阿鲁科尔沁旗| 溧水县| 定陶县| 黄梅县| 淮安市| 邢台县| 红河县| 介休市| 富川| 防城港市| 二连浩特市| 南宁市| 通道| 彰化县| 额尔古纳市| 高要市| 蓬安县| 于田县| 尼玛县| 阳江市| 遂平县| 齐齐哈尔市| 红原县| 韶关市| 福鼎市| 巩留县| 临江市| 苗栗县| 天峨县| 大姚县| 姜堰市| 榆中县| 西林县| 阿鲁科尔沁旗| 游戏| 昭平县| 红桥区| 泽州县| 内黄县| 冷水江市|