Springboot mini - Solon詳解(九)- 渲染控制之定製統一的接口輸出

Springboot min -Solon 詳解系列文章:
Springboot mini - Solon詳解(一)- 快速入門
Springboot mini - Solon詳解(二)- Solon的核心
Springboot mini - Solon詳解(三)- Solon的web開發
Springboot mini - Solon詳解(四)- Solon的事務傳播機制
Springboot mini - Solon詳解(五)- Solon擴展機制之Solon Plugin
Springboot mini - Solon詳解(六)- Solon的校驗框架使用、定製與擴展
Springboot mini - Solon詳解(七)- Solon Ioc 的註解對比Spring及JSR330
Springboot mini - Solon詳解(八)- Solon的緩存框架使用和定製
Springboot mini - Solon詳解(九)- 渲染控制之定製統一的接口輸出
Springboot mini - Solon詳解(十)- 怎麼用 Solon 開發基於 undertow jsp tld 的項目?html

下面這個場景是特地爲此文設計出來的。萬一有相似的出現了。。。Springboot mini -Solon 能夠給你一個so easy的支持。java

Solon 特性之一:git

可以讓控制器實現 Render,從而接管控制器的渲染動做。github

1、定義個接口基類,並實現渲染接口

渲染邏輯以下:web

  1. 若是對象是null,跳過無論
  2. 若是是String,直接輸出
  3. 若是是ONode,作爲Json輸出
  4. 若是是UapiCode,將其轉爲Result,再序列化爲Json輸出
  5. 若是是Throwable,將其轉爲Result,再序列化爲Json輸出
  6. 若是是其它數據,直接序列化爲Json輸出

代碼:api

//這個註解可繼承,用於支持子類的驗證
//
@Valid
public class UapiBase implements Render {
    @Override
    public void render(Object obj, Context ctx) throws Throwable {
        if (obj == null) {
            return;
        }

        if (obj instanceof String) {
            ctx.output((String) obj);
        } else {
            if (obj instanceof ONode) {
                ctx.outputAsJson(((ONode) obj).toJson());
            } else {
                if (obj instanceof UapiCode) {
                    //此處是重點,把一些特別的類型進行標準化轉換
                    //
                    UapiCode err = (UapiCode) obj;
                    obj = XResult.failure(err.getCode(), UapiCodes.getDescription(err));
                }

                if (obj instanceof Throwable) {
                    //此處是重點,把異常進行標準化轉換
                    //
                    Throwable err = (Throwable) obj;
                    obj = XResult.failure(err.getMessage());
                }

                ctx.outputAsJson(ONode.stringify(obj));
            }
        }
    }
}

2、接口示例

1. 白名單接口

此接口作個白名單檢測。若是成功,則返加符串:OK緩存

@Controller
public class CMD_run_whitelist_check extends UapiBase {
    //此處的@NotEmpty驗證,若是沒經過會拋出UapiCode
    @NotEmpty({"type", "value"})
    @Mapping("/run/whitelist/check/")
    public String cmd_exec(Context ctx, String type, String value) throws Exception {
        String tags = ctx.param("tags", "");

        if (tags.contains("client")) {
            if (DbWaterCfgApi.whitelistIgnoreClient()) {
                return "OK";
            }
        }

        if (DbWaterCfgApi.isWhitelist(tags, type, value)) {
            return ("OK");
        } else {
            return (value + ",not is whitelist!");
        }
    }
}

2. 通知推送接口

此接口只能白名單裏的IP方可調用。執行後返回:Resultapp

//此處的@Whitelist驗證,若是沒經過會拋出UapiCode
@Whitelist
@Controller
public class CMD_run_push extends UapiBase {
    //此處的@NotEmpty驗證,若是沒經過會拋出UapiCode
    @NotEmpty({"msg", "target"})
    @Mapping("/run/push/")
    public Result cmd_exec(String msg, String target) throws Exception {

        List<String> list = new ArrayList<String>();
        for (String str : target.split(",")) {
            if (str.equals("@alarm")) {
                List<String> mobiles = DbWaterCfgApi.getAlarmMobiles();

                list.addAll(mobiles);
            } else {
                list.add(str);
            }
        }

        String rest = ProtocolHub.heihei.push(Config.water_service_name, list, msg);

        if (TextUtils.isEmpty(rest) == false) {
            return Result.succeed(ONode.load(rest));
        } else {
            return Result.failure();
        }
    }
}

3. 配置獲取接口

此接口返回一組配置,以ONode類型返回框架

//@Logging是個攔截器,會對請求輸入進行記錄
@Logging
//此處的@Whitelist驗證,若是沒經過會拋出UapiCode
@Whitelist
@Controller
public class CMD_cfg_get extends UapiBase {
    //此處的@NotEmpty驗證,若是沒經過會拋出UapiCode
    @NotEmpty("tag")
    @Mapping("/cfg/get/")
    public ONode cmd_exec(Context ctx, String tag) throws Throwable {
        ONode nList = new ONode().asObject();

        if (TextUtils.isEmpty(tag) == false) {
            List<ConfigModel> list = DbWaterCfgApi.getConfigByTag(tag);

            Date def_time = new Date();

            for (ConfigModel m1 : list) {
                if (m1.update_fulltime == null) {
                    m1.update_fulltime = def_time;
                }

                ONode n = nList.getNew(m1.key);
                n.set("key", m1.key);
                n.set("value", m1.value);

                if (m1.update_fulltime == null) {
                    n.set("lastModified", 0);
                } else {
                    n.set("lastModified", m1.update_fulltime.getTime());
                }
            }
        }

        return nList;
    }
}

此文的渲染控制重點是對拋出來的UapiCode和Throwable,進行有效的控制並以統一的Result形態輸出。對外接口開發時,仍是效果可期的。固然,也能夠用此特性乾點別的什麼事兒。jsp

附:Solon項目地址

相關文章
相關標籤/搜索