Solon详解系列文章:
Solon详解(一)- 快速入门
Solon详解(二)- Solon的核心
Solon详解(三)- Solon的web开发
Solon详解(四)- Solon的事务传播机制
Solon详解(五)- Solon扩展机制之Solon Plugin
Solon详解(六)- Solon的校验扩展框架使用与扩展
Solon详解(七)- Solon Ioc 的注解对比Spring及JSR330
Solon详解(八)- Solon的缓存框架使用和定制
下面这个场景是特意为此文设计出来的。万一有类似的出现了。。。Solon 可以给你一个so easy的支持。
Solon 特性之一:
可让控制器实现XRender,从而接管控制器的渲染动作。
一、定义个接口基类,并实现渲染接口渲染逻辑如下:
如果对象是null,跳过不管
如果是String,直接输出
如果是ONode,做为Json输出
如果是UapiCode,将其转为XResult,再序列化为Json输出
如果是Throwable,将其转为XResult,再序列化为Json输出
如果是其它数据,直接序列化为Json输出
代码:
//这个注解可继承,用于支持子类的验证 // @XValid public class UapiBase implements XRender { @Override public void render(Object obj, XContext 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)); } } } } 二、接口示例 1. 白名单接口此接口做个白名单检测。如果成功,则返加符串:OK
@XController public class CMD_run_whitelist_check extends UapiBase { //此处的@NotEmpty验证,如果没通过会抛出UapiCode @NotEmpty({"type", "value"}) @XMapping("/run/whitelist/check/") public String cmd_exec(XContext 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方可调用。执行后返回:XResult
//此处的@Whitelist验证,如果没通过会抛出UapiCode @Whitelist @XController public class CMD_run_push extends UapiBase { //此处的@NotEmpty验证,如果没通过会抛出UapiCode @NotEmpty({"msg", "target"}) @XMapping("/run/push/") public XResult 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 XResult.succeed(ONode.load(rest)); } else { return XResult.failure(); } } } 3. 配置获取接口此接口返回一组配置,以ONode类型返回
//@Logging是个拦截器,会对请求输入进行记录 @Logging //此处的@Whitelist验证,如果没通过会抛出UapiCode @Whitelist @XController public class CMD_cfg_get extends UapiBase { //此处的@NotEmpty验证,如果没通过会抛出UapiCode @NotEmpty("tag") @XMapping("/cfg/get/") public ONode cmd_exec(XContext 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,进行有效的控制并以统一的XResult形态输出。对外接口开发时,还是效果可期的。当然,也可以用此特性干点别的什么事儿。