Solon detailed - custom unified interface output for rendering control

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:

  1. If the object is null, skip regardless
  2. If it is String, output directly
  3. If it is ONode, output as Json
  4. If it is UapiCode, convert it to XResult, and then serialize it to Json output
  5. If it is Throwable, convert it to XResult, and then serialize it to Json output
  6. 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.

Tags: Java mvc solon

Posted by Ethan28 on Sat, 14 May 2022 09:24:08 +0300