1. 程式人生 > >Solon詳解(六)- 定製業務級別的驗證註解

Solon詳解(六)- 定製業務級別的驗證註解

> Solon詳解系列文章: > [Solon詳解(一)- 快速入門](https://www.cnblogs.com/noear/p/13520109.html) > [Solon詳解(二)- Solon的核心](https://www.cnblogs.com/noear/p/13520125.html) > [Solon詳解(三)- Solon的web開發](https://www.cnblogs.com/noear/p/13520142.html) > [Solon詳解(四)- Solon的事務傳播機制](https://www.cnblogs.com/noear/p/13545461.html) > [Solon詳解(五)- Solon擴充套件機制之Solon Plugin](https://www.cnblogs.com/noear/p/13547433.html) > [Solon詳解(六)- 定製業務級別的驗證註解](https://www.cnblogs.com/noear/p/13548769.html) 在業務的實現過程中,尤其是對外介面開發,我們需要對請求進行大量的驗證並返回錯誤狀態碼和描述。lombok 框架有很多很讚的註解,但是人家是throw一個異常,這與有些需求不一定能匹配。 該文將基於Solon的一些擴充套件基礎,簡單的實現一套定製的業務驗證機制。效果如下: ```java @XController public class UserController extends VerifyController{ @RepeatSubmit //重複提交驗證 @Whitelist //IP白名單驗證 @NotNull({"name", "mobile", "icon", "code"}) //非NULL驗證 @XMapping("/user/add") public void addUser(UserModel user){ //... } } ``` ### 一、定製開始 #### 1、先定義一組驗證註解 ```java @Inherited @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface NotNull { String[] value(); } @Inherited @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Whitelist { } //... 更多略 ``` #### 2、然後,定義一個驗證用的攔截器 ```java // //Solon裡的所有攔截器,也都是 XHandler // public class VerifyInterceptor implements XHandler { @Override public void handle(XContext ctx) throws Throwable { //獲取上下文中的XAction // XAction action = ctx.attr("action"); if (action != null) { handle0(ctx, action); } } protected void handle0(XContext ctx, XAction action) throws Throwable { //這裡的順序,要與業務的期望順序匹配 //白名單 checkWhitelist(ctx, action); //不能為Null checkNotNull(ctx, action); //...更多略 } protected void checkWhitelist(XContext ctx, XAction action) throws Throwable{ if(ctx.getHandled()){ return; } Whitelist anno = action.method().getAnnotation(Whitelist.class); if (anno != null) { String ip = IpUtils.getIP(ctx); if (WhitelistApi.existsOfServerIp(ip) == false) { ctx.setHandled(true); ctx.render(UapiCodes.CODE_16); } } } protected void checkNotNull(XContext ctx, XAction action) throws Throwable{ if(ctx.getHandled()){ return; } NotNull anno = action.method().getAnnotation(NotNull.class); if (anno != null) { checkParamsIsOk(ctx, false, anno.value()); } } } ``` #### 3、再是,定義一個支援驗證的控制器基類 ```java // // 建立一個有驗證攔截器的基類;@XBefore 註解是可繼承的... // @XBefore({VerifyInterceptor.class}) public class VerifyController { } ``` 完工了 ### 二、附:關於 XContext 的部分擴充套件屬性 Solon 的上下文物件:XContext,有一組可擴充套件屬性的介面:attr(), attrSet(), attrMap()。用於記錄處理過程中的資料或物件。 以下是框架在執行過程中已記錄的擴充套件屬性: | 擴充套件屬性 | 說明 | | -------- | -------- | | ctx.attr("controller") | 獲取當前控制器 | | ctx.attr("action") | 獲取當前活動 | | ctx.result | 獲取當前活動的執行結果,可用於統一的業務日誌記錄 | | ctx.attr("error") | 獲取當前錯誤 | | ctx.attr("output") | 獲取當前序列化輸出,可用於統一的業務日誌記錄