如何编写 json 字段来检索它?

How do I write a json field to retrieve this?

我目前在我的代码中使用 json 来检索布尔值数组。但是,我正在添加一个子字段以在其中实现另一个数组,但我不擅长 json 并且有点卡住如何去做。 到目前为止,这是我的代码:

字段值:

 public enum Field {



       /**
         * Runtime Config Fields
         **/
        FIELD_CAN_CHANGE_PASSWORD("canChangePassword", true, canUpdate),
        FIELD_MAX_AUTO_DOWNLOAD_SIZE("maxAutoDownloadSize", 5000000L),
        FIELD_ALWAYS_REAUTHENTICATE("alwaysReauthenticate", false, canUpdate),
        FIELD_CAN_START_CALL("canStartCall", false),
        FIELD_ROOMS_ENABLED("roomsEnabled", !Core.isMessenger()),
        FIELD_CAN_CREATE_ROOM("canCreateRoom", !Core.isMessenger(), canUpdate),
        FIELD_MAX_ENVELOPE_TTL("maxTTL", Core.isMessenger() ? 518400L : 31536000L, canUpdate),
        FIELD_MAX_BURN_ON_READ_TTL("maxBOR", 0L, canUpdate),
        FIELD_MAX_UPLOAD_SIZE("maxUploadSize", -1L, true),
        FIELD_FRIEND_FINDER("friendFinder", !Core.isEnterprise(), canUpdate),
        FIELD_ONLY_SHOW_IN_NETWORK_CONTACTS("onlyShowInNetwork", false),
        FIELD_CAN_ADD_CONTACT("canAddContact", true, canUpdate),
        FIELD_FORCE_DEVICE_LOCKOUT("forceDeviceLockout", 5L, canUpdate),
        FIELD_VERIFICATION_MODE("verificationMode", VerificationMode.OPTIONAL.getValue(), true),
        FIELD_ENABLE_NOTIFICATION_PREVIEW("enableNotificationPreview", true, true),
        FIELD_DIRECTORY_ENABLED("directoryEnabled", true, true);

        public String fieldName;
        public Object defaultValue;
        public boolean updateFromServer;

        Field(String key, Object defaultValue) {
            this(key, defaultValue, true);
        }

        Field(String key, Object defaultValue, boolean updateFromServer) {
            this.fieldName = key;
            this.defaultValue = defaultValue;
            this.updateFromServer = updateFromServer;
        }
    }

在字段中输入值:

 private void putValueForField(JSONObject configuration, Field field) {
        try {
            if (configuration.isNull(field.fieldName)) {
                Object value = field.defaultValue;
                if (value instanceof long[]) {
                    JSONArray array = new JSONArray();
                    for (long obj : (long[]) field.defaultValue) {
                        array.put(obj);
                    }
                    value = array;
                }
                runtimeConfiguration.put(field.fieldName, value);
            } else {
                runtimeConfiguration.put(field.fieldName, configuration.get(field.fieldName));
            }
        } catch (JSONException e) {

        }
    }

获取值:

 private Object getValueForField(Field field) {
        if (runtimeConfiguration.has(field.fieldName) && field.updateFromServer) {
            try {
                Object value = runtimeConfiguration.get(field.fieldName);
                if (value instanceof JSONArray) {
                    JSONArray values = (JSONArray) value;
                    if (values.get(0) instanceof Number) {
                        long[] retVals = new long[values.length()];
                        for (int i = 0; i < values.length(); i++) {
                            retVals[i] = ((Number) values.get(i)).longValue();
                        }
                        return retVals;
                    }
                } else if (value instanceof Number) {
                    return ((Number) value).longValue();
                } else {
                    return value;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return field.defaultValue;
    }

使用上述字段的方法之一:

 public boolean canChangePassword() {
        return (boolean) getValueForField(Field.FIELD_CAN_CHANGE_PASSWORD);
    }

我的新 json 是:

{"enableNotificationPreview":true,"destructOnRead":[30,60,300],"alwaysReauthenticate":false,"forceDeviceLockout":0,"permmod":1516894585,"maxBOR":0,"roomsEnabled":true,"directoryEnabled":true,"canStartCall":true,"canAddContact":true,"legacyDownload":false,"verificationMode":1,"restrictedAdmin":false,"canChangePassword":true,"friendFinder":true,"NEWVALUE":{"canStartNewValue1":true,"canStartroupValue":true,"canVideoCall":true,"canStartRoomValue":true,"canAddtoValue":true,"canStartValueshare":true},"canCreateRoom":true,"maxTTL":2592000,"onlyShowInNetwork":false,"maxUploadSize":null,"availableEnvelopeTTL":[0,600,3600,86400,604800,2592000],"maxAutoDownloadSize":7340032}

我在哪里插电:

"NEWVALUE":{"canStartNewValue1":true,"canStartroupValue":true,"canVideoCall":true,"canStartRoomValue":true,"canAddtoValue":true,"canStartValueshare":true}

不确定如何更新我的 putValueForField 以反映这个新 json 和相应的字段。任何的想法?

要从 json 对象检查和检索 JSONObject,您可以修改方法以检查 instance of JSONObject 并为其赋值。

 private void putValueForField(JSONObject configuration, Field field) {
        try {
            if (configuration.isNull(field.fieldName)) {
                Object value = field.defaultValue;
                if (value instanceof long[]) {
                    JSONArray array = new JSONArray();
                    for (long obj : (long[]) field.defaultValue) {
                        array.put(obj);
                    }
                    value = array;
                }
                // this is how you check if fieldName is of type jsonobject
                if (value instanceof JSONObject) {
                    JSONObject valueObject = configuration.getJSONObject(field.fieldName);
                    value = valueObject;
                }
                runtimeConfiguration.put(field.fieldName, value);
            } else {
                runtimeConfiguration.put(field.fieldName, configuration.get(field.fieldName));
            }
        } catch (JSONException e) {

        }
    }

根据我的理解,您只是从 JSON 获取值并在这种情况下将其保存在字段中:

我认为在这种方法中你最终只是将所有值存储为 object 只有这样在检索时你必须再次进行所有这些检查。

如果您从服务器获得具有固定对象字段和对象值的响应,您应该从该配置中创建一个 class,您将知道它的确切内容 return。那真的会让生活更轻松。

或者,如果您只需要 get/update 的配置或放置值,您可以在 json 对象本身中维护它 Android JSON doc reference

例如假设您有这个 json 对象本身,我在下面添加了工作示例,希望这对您有所帮助。

import org.json.*;

class Main {
    public static void main(String[] args) throws JSONException {
        String jsn = "{\"enableNotificationPreview\":true,\"destructOnRead\":[30,60,300],\"" +
                "alwaysReauthenticate\":false,\"forceDeviceLockout\":0,\"NEWVALUE\":{\"canStartNewValue1\":true," +
                "\"canStartroupValue\":true,\"canVideoCall\":true,\"canStartRoomValue\":true},\"canCreateRoom\":true," +
                "\"maxTTL\":2592000,\"onlyShowInNetwork\":false,\"maxUploadSize\":null,\"availableEnvelopeTTL\"" +
                ":[0,600,3600,86400,604800,2592000],\"maxAutoDownloadSize\":7340032}";

        JSONObject jsnObj = new JSONObject(jsn);
        Object enableNotificationPreview = jsnObj.get("enableNotificationPreview");
        // or if you know it will be boolean
        boolean enableNotificationPreviewBool = jsnObj.getBoolean("enableNotificationPreview");
        System.out.println(enableNotificationPreview);
//        output : true
        System.out.println(enableNotificationPreviewBool);
//        output : true

        JSONObject NEWVALUEObj = jsnObj.getJSONObject("NEWVALUE");
//        now again you can extract values from it
        boolean canStartNewValue1 = NEWVALUEObj.getBoolean("canStartNewValue1");
        System.out.println(canStartNewValue1);
        NEWVALUEObj.put("canStartNewValue1", false);
        System.out.println(NEWVALUEObj.toString());
        jsnObj.put("forceDeviceLockout", 23456);
//        now canStartNewValue1 value is changed to false in the object
//        and forceDeviceLockout is also 23456
        System.out.println(jsnObj.toString());
    }
}