博客 / 詳情

返回

SpringBoot定義優雅全局統一Restful API 響應框架完結撒花篇封裝starter組件

之前我們已經,出了一些列文章。 講解如何封統一全局響應Restful API。

感興趣的可以看我前面幾篇文章 (整個starter項目發展史)

SpringBoot定義優雅全局統一Restful API 響應框架

SpringBoot定義優雅全局統一Restful API 響應框架二

SpringBoot定義優雅全局統一Restful API 響應框架三

SpringBoot定義優雅全局統一Restful API 響應框架四

SpringBoot定義優雅全局統一Restful API 響應框架五

SpringBoot定義優雅全局統一Restful API 響應框架六

後續我萌生裏新的想法,SpringBoot 不是提供了自己的starter。我們也可以自定義starter嗎,於是我定義了rest-api-spring-boot-starter,已經發布到maven中央倉庫,對之前Restful API 響應框架 做了集成和重構,

在這個基礎上我又總結封裝了我自己工作以常用的很多工具,結合SpringBoot 封裝了全能的工具。 已經更新到了1.3.0 不耦合任何依賴 請使用最新版本

目前更新版本1.3.0 功能如下

  1. 支持一鍵配置自定義RestFull API 統一格式返回
  2. 支持RestFull API 錯誤國際化
  3. 支持全局異常處理,全局參數驗證處理
  4. 業務錯誤斷言工具封裝,遵循錯誤優先返回原則
  5. redis工作封裝。支持所有key操作工具
  6. RestTemplate 封裝 POST,GET 請求工具
  7. 日誌集成。自定義日誌路徑,按照日誌等級分類,支持壓縮和文件大小分割。按時間顯示
  8. 工具庫集成 集成了lombok,hutool,commons-lang3,guava。不需要自己單個引入
  9. 集成mybatisPlus一鍵代碼生成

github 地址

下面我講一下怎麼在項目中去使用

我們新建一個SpringBoot Web項目

我們只需要在pom中引入即可

 <dependency>
            <groupId>cn.soboys</groupId>
            <artifactId>rest-api-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>

在啓動類或者配置類中加上 @EnableRestFullApi 註解即可

RestFull API使用

這樣在項目controller中我們寫普通的請求如:

 @PostMapping("/chat")
    public HashMap chatDialogue() {
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

返回的就是全局統一RestFull API

我們也可以這麼寫

提供了很多返回方法。

當然如果你這個接口不想包裝成全局返回,想自定義單獨返回 如我們只需要在方法上加上@NoRestFulApi 註解即可

   @PostMapping("/chat")
    @NoRestFulApi
    public HashMap chatDialogue() {
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

就不會對返回內容進行任何包裝處理。

全局錯誤攔截,參數校驗

幫你封裝好了所有http常見錯誤,和所有請求類型和參數錯誤。

如請求錯誤

{
    "success": false,
    "code": "405",
    "msg": "方法不被允許",
    "timestamp": "2023-07-03 22:36:47",
    "data": "Request method 'GET' not supported"
}

請求資源不存在

{
    "success": false,
    "code": "404",
    "msg": "請求資源不存在",
    "timestamp": "2023-07-03 22:42:35",
    "data": "/api"
}

參數校驗錯誤

驗證Studen對象參數

/**
 * @author 公眾號 程序員三時
 * @version 1.0
 * @date 2023/6/26 22:10
 * @webSite https://github.com/coder-amiao
 */
@Data
public class Student {
    @NotBlank
    private String nam;
    @NotBlank
    private String hobby;
}
    @PostMapping("/chat")
    public HashMap chatDialogue(@Validated  Student student) {
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

請求結果

JSON Body參數

    @PostMapping("/chat")
    public HashMap chatDialogue(@RequestBody @Validated  Student student) {
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

錯誤國際化

內置封裝錯誤默認支持英文和中文兩種國際化。你不做任何配置自動支持

如果需要內置支持更多語言,覆蓋即可。

自定義自己錯誤國際化和語言

  i18n:
    # 若前端無header傳參則返回中文信息
    i18n-header: Lang
    default-lang: cn
    message:
      # admin
      internal_server_error:
        en: Internal Server Error
        cn: 系統錯誤
      not_found:
        en: Not Found
        cn: 請求資源不存在

message 對應錯誤提示
對應internal_server_error 自定義
下面語言自己定義 和前端傳入i18n-header 對應上,就顯你定義錯誤語言

我不傳錯誤國際化默認就是中文在 default-lang: cn
進行配置

當我傳入 指定語言 就會按照你配置的國際化自定義返回錯誤提示

自定義錯誤響應

如果我內置錯誤無法滿足你業務需求,你也可以自定義自己錯誤碼

你自定義錯誤枚舉 只需要實現ResultCode接口即可

package cn.soboys.restapispringbootstarter;

import cn.soboys.restapispringbootstarter.i18n.I18NKey;

/**
 * @author 公眾號 程序員三時
 * @version 1.0
 * @date 2023/6/26 10:21
 * @webSite https://github.com/coder-amiao
 * 響應碼接口,自定義響應碼,實現此接口
 */
public interface ResultCode extends I18NKey {

    String getCode();

    String getMessage();

}
````

如果要支持國際化還需要實現國際化接口**I18NKey** 參考我內部**HttpStatus**實現即可

package cn.soboys.restapispringbootstarter;

import cn.soboys.restapispringbootstarter.i18n.I18NKey;

/**

  • @author 公眾號 程序員三時
  • @version 1.0
  • @date 2023/6/26 11:01
  • @webSite https://github.com/coder-amiao
    */

public enum HttpStatus implements ResultCode, I18NKey {

/**
 * 系統內部錯誤
 */
INTERNAL_SERVER_ERROR("500", "internal_server_error"),
BAD_GATEWAY("502", "bad_gateway"),
NOT_FOUND("404", "not_found"),
UNAUTHORIZED("401", "unauthorized"),
FORBIDDEN("403", "forbidden"),
METHOD_NOT_ALLOWED("405", "method_not_allowed"),
REQUEST_TIMEOUT("408", "request_timeout"),

INVALID_ARGUMENT("10000", "invalid_argument"),
ARGUMENT_ANALYZE("10001", "argument_analyze"),
BUSINESS_EXCEPTION("20000", "business_exception");


private final String value;

private final String message;

HttpStatus(String value, String message) {
    this.value = value;
    this.message = message;
}


@Override
public String getCode() {
    return value;
}

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


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

}

rest-api:
enabled: false
i18n:

# 若前端無header傳參則返回中文信息
i18n-header: Lang
default-lang: cn
message:
  # admin
  internal_server_error:
    en: Internal Server Error
    cn: 系統錯誤
  bad_gateway:
    en: Bad Gateway
    cn: 錯誤的請求
  unauthorized:
    en: Unauthorized
    cn: 未授權
  forbidden:
    en: Forbidden
    cn: 資源禁止訪問
  method_not_allowed:
    en: Method Not Allowed
    cn: 方法不被允許
  request_timeout:
    en: Request Timeout
    cn: 請求超時
  invalid_argument:
    en: Invalid Argument {}
    cn: 參數錯誤 {}
  argument_analyze:
    en: Argument Analyze {}
    cn: 參數解析異常 {}
  business_exception:
    en: Business Exception
    cn: 業務錯誤
  not_found:
    en: Not Found
    cn: 請求資源不存在

![](https://images.soboys.cn/202307040127708.png)

![](https://images.soboys.cn/202307040127574.png)

![](https://images.soboys.cn/202307042336110.png)

![](https://images.soboys.cn/202307042337644.png)

內部錯誤不需要做任何配置,自動支持國際化。如果需要支持更多語言,可以自定義進行覆蓋。

# 業務異常斷言

在項目開發中我們有時需要封裝自己異常類,信息我封裝了統一的錯誤異常類。
**BusinessException** 對業務異常類做了全局錯誤攔截,

封裝·了統一業務異常斷言工具,遵循錯誤優先返回原則。代碼更優雅

![](https://images.soboys.cn/202307040915661.png)
@GetMapping("/exception")
public Result exception(){
    Student s=null;
    Assert.isFalse(s==null,"學生不能為空");
    return Result.buildSuccess();
}
拋出統一業務異常


![](https://images.soboys.cn/202307040920873.png)

當然如果你要定義自己的異常類。可以定義自己異常類·繼承我的**BusinessException**


# Redis 工具庫使用
進一步封裝的對**Redis**所以相關key,value操作,在使用redis工具庫時候。我們需要引入

<dependency>

        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

默認不會幫你引入。

然後在使用時候注入就行
````
@Autowired
    private RedisTempUtil redisTempUtil;
````

![](https://images.soboys.cn/202307040939790.png)
@GetMapping("/redis")
public Result redis() {
    redisTempUtil.set("test", "123456");
    return Result.buildSuccess();
}


@GetMapping("/redis/get")
public Result redisGet() {
    String value = redisTempUtil.get("test").toString();
    log.info("redis值{}", value);
    return Result.buildSuccess();
}
# RestTemplate 請求工具
進一步封裝了RestTemplate請求 Post和GET
項目中使用時注入

@Autowired

private RestFulTemp restFulTemp;

![](https://images.soboys.cn/202307040957101.png)
@GetMapping("/doGet")
public Result doGet() {
    ResponseEntity<String> response = restFulTemp.doGet("http://127.0.0.1:8000/redis/get");
    return Result.buildSuccess(response.getBody());
}

# 日誌使用
進一步封裝了 日誌處理達到開箱即用。在屬性文件中配置相關日誌配置即可

rest-api:
enabled: false
logging:

path: ./logs   #日誌存儲路徑(服務器上絕對)
max-history: 90 # 保存多少天
max-file-size: 3MB  # 每個文件大小
max-total-size-cap: 1GB  #總文件大小超過多少壓縮
level-root: INFO    # 這裏的INFO可以替換為其他日誌等級,如DEBUG, WARN, ERROR, TRACE, FATAL, OFF等。 日誌等級由低到高分別是debugger-info-warn-error

如果你的屬性文件不做任何日誌配置,默認日誌就是上面這樣配置。

# 集成mybatisPlus一鍵代碼生成
在項目中我們會頻繁使用到mybatisPlus 但是簡單的模板代碼我們一鍵生成就好。 默認不依賴mybatisPlus任何相關包。如果需要使用自動代碼生成引入mybatisPlus 代碼生成依賴包即可。

<!--生成器依賴-->

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.4.1</version>
        <optional>true</optional>
    </dependency>
    <!-- MySQL -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.28</version>
        <optional>true</optional>
    </dependency>
    <!--代碼生成依賴的模板引擎-->
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.31</version>
        <optional>true</optional>
    </dependency>
你可以直接寫測試類,然後直接去調用代碼生成即可

public class Test {

public static void main(String[] args) {
    GenerateCodeConfig config=new GenerateCodeConfig();
    config.setDriverName("com.mysql.cj.jdbc.Driver");
    config.setUsername("root");
    config.setPassword("root");
    config.setUrl("jdbc:mysql://127.0.0.1:3306/ry?useUnicode=true&useSSL=false&characterEncoding=utf8");
    //生成代碼保存路徑,不設置就是當前項目下路徑,如何設置請使用絕對路徑
    config.setProjectPath("superaide");
    config.setPackages("cn.soboys.superaide");
    MyBatisPlusGenerator.generate(config);
}

}


效果如下
![](https://images.soboys.cn/202307050049316.png)


關注公眾號,**程序員三時** 持續輸出優質內容 希望給你帶來一點啓發和幫助

下篇文章就這個源碼剖析講解 如何封裝自己的**stater**













user avatar jingsewu 頭像 cicadasmile 頭像 leefj 頭像
3 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.