How do I write a json field to retrieve this?

此生再无相见时 提交于 2019-12-24 09:49:03

问题


I am currently using json for my code to retrieve an array of boolean values. However, i am adding a subfield to achieve another array within, but I am not good with json and kind of stuck how to go about it. Here's my code so far:

field values :

 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;
        }
    }

putting values in field:

 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) {

        }
    }

getting values :

 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;
    }

one of the methods using the fields above:

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

My new json is :

{"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}

where I am plugging in :

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

Not sure how to update my putValueForField to reflect this new json and the corresponding fields. Any idea?


回答1:


To check and retrieve JSONObject from the json object you can modify your method to check for instance of JSONObject and assign value to it.

 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) {

        }
    }

Form what I can understand you are just getting the values from JSON and saving it in field in that case:

I think in this method ultimately you are just storing all values as object only so while retrieving you have to do all this check again.

If you are getting the response from server with fixed Object fields and object values you should be creating a class from that configuration where you will know what exactly it will return. That would really make life easier.

Or maybe if you just need the configuration to get/update or put values you can maintain it in json object itself Android JSON doc reference

For example lets say you have this jsonobject itself, I have added the working example below, hope this helps.

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());
    }
}


来源:https://stackoverflow.com/questions/48447684/how-do-i-write-a-json-field-to-retrieve-this

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!