Spring Easy
用途
通過自動配置,實現了一些國內 Spring Boot 開發時需要在 Spring Boot 框架基礎上完成的一些配置工作,可以提升基于 Spring Boot 開發 Web 應用的效率。
安裝
使用 Maven 進行包管理,可以從中央倉庫安裝依賴:
<dependency><groupId>cn.icexmoon</groupId><artifactId>spring-easy-boot-starter</artifactId><version>1.0.0</version>
</dependency>
功能說明
封裝控制器方法返回值
提供對 JSON 返回的統一封裝。
比如 Controller 方法:
@GetMapping("/say")
public Map<String, String> say() {return Map.of("msg", "hello");
}
Spring Boot 默認返回:
{"msg": "hello"
}
使用本應用后:
{"success": true,"message": null,"data": {"msg": "hello"}
}
這里利用返回值處理器 ResponseBodyAdvice 對控制器方法的返回值進行統一封裝,將其封裝為 Result 對象的 data 屬性,然后由 Spring 的 ResponseBody 返回值處理器(Return Value Resolver)進行處理,即使用消息轉換器(默認為 Jackson)將 Result 對象解析成 JSON 字符串作為響應報文體返回。
需要注意的是,由 @Response 注解標記,且返回類型是 String 的控制器方法比較特殊:
@GetMapping("/msg")
public String msg() {return "<h1>hello</h1>";
}
這個控制器方法的返回值不走 ResponseBody 返回值處理器,會被另一個返回值處理器處理,處理方式也很簡單,直接作為字符串填充到響應報文體中返回。這也符合開發者需要,因為這種方式定義的控制器方法,通常會直接返回 Html 片段等,不需要返回值處理器進行消息轉換等額外處理。
因此,對于這種類型的控制器方法,本項目同樣不會進行封裝,以便行為和 Spring Boot 的默認實現保持一致。
如果你需要返回給前端的內容只有一個字符串,且希望返回標準封裝的形式,可以直接構造 Result
對象并返回:
@GetMapping("/msg2")
public Result<String> msg2() {return Result.success("hello", null);
}
本項目不會對 Result 類型的返回進行再次包裝。
對于其他形式的基本類型返回,本項目都會進行封裝,比如:
@GetMapping("/void")
public void voidMethod() {
}@GetMapping("/boolean")
public boolean booleanMethod() {return false;
}@GetMapping("/int")
public int intMethod() {return 11;
}
都會包裝并返回 Result 對象的 JSON 字符串。
統一處理并返回錯誤信息
項目使用異常處理器(Exception Handler)ErrorControllerAdvice 對異常進行統一處理,并封裝成標準返回值返回。
比如會產生異常的控制器方法:
@GetMapping("/default")
public Result<Void> defaultError() {int i = 1 / 0;return Result.success();
}
返回報文:
{"success": false,"message": "/ by zero","data": null
}
控制臺中會由cn.icexmoon.springeasy.boot.ErrorControllerAdvice
輸出相關異常信息日志,日志級別為error
。
業務層面產生的異常,比如缺少用戶信息等,應當使用自定義異常 BusinessException,這個異常同樣會被捕獲并封裝成統一格式返回,區別在于默認異常的 HTTP 狀態碼是 500,業務異常的 HTTP 狀態碼是 200。
可以在任意需要返回業務錯誤的地方直接拋出 BusinessException,或者在需要的時候將其它類型的異常包裝成業務異常拋出:
@GetMapping("/business")
public Result<Void> businessError() {try {int i = 1 / 0;} catch (Throwable e) {Map<String, ?> exceptionData = Map.of("cause", e,"businessCode", "1001");throw BusinessException.builder().cause(e).message(e.getMessage()).data(exceptionData).build();}return Result.success();
}
BusinessException 的 data 屬性可以存放需要傳遞給前端的額外信息,它將被保存到 Result 對象的 data 屬性后返回給前端。
對于 Servlet 異常(比如 Filter 產生的),定義了一個控制器 ServletErrorController 進行處理,以同樣的返回標準 Result。控制器方法中只會進行簡單異常信息打印和控制臺異常調用日志輸出:
@ResponseBody
public Result<?> error(HttpServletRequest request) {Throwable error = (Throwable) request.getAttribute((RequestDispatcher.ERROR_EXCEPTION));log.error(error.getMessage(), error);return Result.fail("Servlet 錯誤:" + error.getMessage());
}
如果不滿足需要,可以覆蓋這個 Bean 進行自定義。
該控制器默認使用 /error
路徑進行內部跳轉,如果你不想使用該路徑(通常是被其它控制器方法已經占用),可以通過配置文件中的屬性進行修改:
spring-easy:boot-starter:error-page-path: /servlet_error
時間類型轉換
項目添加了針對 LocalDateTime
和 LocalDate
的類型轉換器,以支持國內常見的 yyyy-MM-dd HH:mm:ss
或yyyy-MM-dd
格式的日期/時間字符串轉換。
啟用本項目后可以直接通過 URL 的查詢參數傳遞時間字符串:
localhost:8080/hello/time?time=2025-07-09 11:08:03
控制器方法:
@GetMapping("/time")
public LocalDateTime time(@RequestParam LocalDateTime time) {log.info(time.toString());return time;
}
LocalDateTime
類型的@RequestParam
參數可以被正常解析,不需要使用其他額外的類型轉換注解。
為了能夠讓 jackson 正確解析和編碼同樣格式的時間字符串,本項目添加了相應的 jackson 解析器/編碼器。因此如果使用本項目的時間類型轉換功能,最好不要替換 Spring Boot 默認的消息轉換器 jackson。
IEnum 枚舉類型轉換
如果你的項目使用 MyBatisPlus,且實體類中存在枚舉字段,使用IEnum
接口是最方便的:
@TableName(value = "user")
@Data
public class User {public enum Sex implements IDescEnum<Integer> {MALE(5, "男"), FEMALE(6, "女");private final Integer value;private final String desc;Sex(Integer value, String desc) {this.value = value;this.desc = desc;}@Overridepublic Integer getValue() {return value;}@Overridepublic String getDesc() {return desc;}}/****/@TableId(type = IdType.AUTO)private Long id;/*** 姓名*/private String name;/*** 性別 5 男,6 女*/private Sex sex;
}
這里使用的 IDescEnum 接口是對 IEnum 接口的一個擴展,本質是一樣的,只是額外記錄枚舉常量的中文信息。
MyBatisPlus 實現了 Service 層和數據庫的 IEnum 和 int 值的轉換,但如果將 IEnum 類型的枚舉用于控制器方法參數或返回值,就會被 Spring Boot 當做普通的枚舉類型進行處理。
本項目通過添加類型轉換器和 jackson 編碼器/解析器,實現了 int 和 IEnum 枚舉的轉換。
關閉部分功能
本項目默認開啟所有功能,如果要關閉相關功能,可以通過配置文件:
spring-easy:boot-starter:wrap-result: truewrap-error: truetime-converter: trueenum-converter: true
相應的屬性設置為 false 即可。需要更高程度的自由定制可以查看源碼后覆蓋相應的 bean 定義。
示例
spring-easy-test 是一個包含了所有功能的完整 Spring Boot 示例,展示了如何添加本項目以及使用相應功能。
開源
項目使用 Apache 2 許可證開源,倉庫地址 icexmoon/spring-easy。
項目代碼結構為:
- spring-easy-boot-starter,Spring Boot 的自動配置相關
- spring-easy-parent,Maven 依賴版本控制以及項目編譯
- spring-easy-test,一個用于測試/示例的 Spring Boot Web 項目
- spring-easy-util,核心類,包含 jackson 解析器/編碼器、Spring 類型轉換器等
反饋
Issues · icexmoon/spring-easy
更新日志
1.0.0
發布