之前我們已經,出了一些列文章。 講解如何封統一全局響應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 功能如下
- 支持一鍵配置自定義RestFull API 統一格式返回
- 支持RestFull API 錯誤國際化
- 支持全局異常處理,全局參數驗證處理
- 業務錯誤斷言工具封裝,遵循錯誤優先返回原則
- redis工作封裝。支持所有key操作工具
- RestTemplate 封裝 POST,GET 請求工具
- 日誌集成。自定義日誌路徑,按照日誌等級分類,支持壓縮和文件大小分割。按時間顯示
- 工具庫集成 集成了lombok,hutool,commons-lang3,guava。不需要自己單個引入
- 集成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: 請求資源不存在




內部錯誤不需要做任何配置,自動支持國際化。如果需要支持更多語言,可以自定義進行覆蓋。
# 業務異常斷言
在項目開發中我們有時需要封裝自己異常類,信息我封裝了統一的錯誤異常類。
**BusinessException** 對業務異常類做了全局錯誤攔截,
封裝·了統一業務異常斷言工具,遵循錯誤優先返回原則。代碼更優雅

@GetMapping("/exception")
public Result exception(){
Student s=null;
Assert.isFalse(s==null,"學生不能為空");
return Result.buildSuccess();
}
拋出統一業務異常

當然如果你要定義自己的異常類。可以定義自己異常類·繼承我的**BusinessException**
# Redis 工具庫使用
進一步封裝的對**Redis**所以相關key,value操作,在使用redis工具庫時候。我們需要引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
默認不會幫你引入。
然後在使用時候注入就行
````
@Autowired
private RedisTempUtil redisTempUtil;
````

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

@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);
}
}
效果如下

關注公眾號,**程序員三時** 持續輸出優質內容 希望給你帶來一點啓發和幫助
下篇文章就這個源碼剖析講解 如何封裝自己的**stater**