Solon detailed series of articles:
Solon Detailed Explanation (1) - Quick Start
Solon Detailed Explanation (2) - The Core of Solon
Solon Detailed Explanation (3) - Solon's web Development
Solon Detailed Explanation (4) - Solon's Transaction Propagation Mechanism
Solon Detailed Explanation (5) - Solon Plugin of Solon Extension Mechanism
Solon Detailed Explanation (6) - Use and Extension of Solon's Verification Extension Framework
Solon Detailed Explanation (7) - Solon Ioc Annotation Comparison Spring and JSR330
Solon Detailed Explanation (8) - Solon's Cache Framework Usage and Customization
Solon Detailed Explanation (9) - Customized Unified Interface Output of Rendering Control
The following scene is specially designed for this article. In case something like this happens. . . Solon can give you a so easy support.
One of Solon's features:
Allows the controller to implement XRender, which takes over the controller's rendering actions.
1. Define an interface base class and implement the rendering interface
The rendering logic is as follows:
- If the object is null, skip regardless
- If it is String, output directly
- If it is ONode, output as Json
- If it is UapiCode, convert it to XResult, and then serialize it to Json output
- If it is Throwable, convert it to XResult, and then serialize it to Json output
- If it is other data, serialize it directly to Json output
Code:
//This annotation can be inherited and used to support validation of subclasses // @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) { //Here is the point, standardize some special types // UapiCode err = (UapiCode) obj; obj = XResult.failure(err.getCode(), UapiCodes.getDescription(err)); } if (obj instanceof Throwable) { //Here is the point, standardize the exception // Throwable err = (Throwable) obj; obj = XResult.failure(err.getMessage()); } ctx.outputAsJson(ONode.stringify(obj)); } } } }
Second, the interface example
1. Whitelist interface
This interface does a whitelist detection. If successful, return plus string: OK
@XController public class CMD_run_whitelist_check extends UapiBase { //@NotEmpty verification here, if it fails, it will throw 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. Notification push interface
This interface can only be called by IP s in the whitelist. Return after execution: XResult
//@Whitelist verification here, if it fails, it will throw UapiCode @Whitelist @XController public class CMD_run_push extends UapiBase { //@NotEmpty verification here, if it fails, it will throw 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. Configure the acquisition interface
This interface returns a set of configurations, returned as ONode type
//@Logging is an interceptor that records request input @Logging //@Whitelist verification here, if it fails, it will throw UapiCode @Whitelist @XController public class CMD_cfg_get extends UapiBase { //@NotEmpty verification here, if it fails, it will throw 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; } }
The focus of rendering control in this article is to effectively control the thrown UapiCode and Throwable and output them in a unified XResult form. When the external interface is developed, the effect can be expected. Of course, you can also use this feature to do something else.