it-roy-ru.com

JSON jsonObject.optString () возвращает строку "ноль"

Я разрабатываю приложение для Android, которое использует JSON для взаимодействия с сервером, и у меня возникает странная проблема, когда я пытаюсь проанализировать мой файл json.

Это мой JSON с сервера

{
    "street2": null,
    "province": null,
    "street1": null,
    "postalCode": null,
    "country": null,
    "city": null
}

Я получаю значение для City, вызывая String city = address.optString("city", "") для моего адреса Json-object. В этой ситуации я ожидаю, что city будет пустым (вот для чего здесь используется optString, не так ли?), Но на самом деле он содержит строку «null». Поэтому дальнейшие проверки null или isEmpty вернут false, поскольку строка содержит текст. Если я вызываю address.isNull("city"), он возвращает true, что правильно. Только optString терпит неудачу.

Я не смог найти что-либо в Google или Stackoverflow для этой проблемы. Я не очень понимаю, как это может произойти, так как я думал, что optString сделает именно то, что я ожидал. Кто-нибудь знает, что здесь происходит?

49
joschplusa

Вы не одиноки, сталкиваясь с этой проблемой и почесывая голову, думая: «Могли ли они действительно это иметь в виду?» Согласно проблеме AOSP, инженеры Google didсчитают это ошибкой, но они должны были быть совместимы с реализацией org.json, даже совместимы с ошибками. 

Если подумать, это имеет смысл, потому что, если тот же код, который использует те же библиотеки, запущенные в других средах Java, ведет себя по-разному в Android, могут возникнуть серьезные проблемы совместимости при использовании сторонних библиотек. Даже если бы намерения были хорошими, и это действительно исправило ошибки, это открыло бы целую новую банку червей.

Согласно выпуску AOSP :

Поведение является намеренным; мы старались быть совместимыми с ошибками с org.json. Теперь, когда это исправлено, неясно, должны ли мы также исправить наш код. Приложения могли полагаться на это ошибочное поведение.

Если это вызывает у вас горе, я рекомендую вам обойти это, используя другой механизм для проверки на нуль, такой как json.isNull ().

Вот простой способ помочь вам:

/** Return the value mapped by the given key, or {@code null} if not present or null. */
public static String optString(JSONObject json, String key)
{
    // http://code.google.com/p/Android/issues/detail?id=13830
    if (json.isNull(key))
        return null;
    else
        return json.optString(key, null);
}
81
Matt Quigley

У вас есть 2 варианта:

1) Отправить полезную нагрузку JSON с нулевыми значениями

{
"street2": "s2",
"province": "p1",
"street1": null,
"postalCode": null,
"country": null,
"city": null
}

Вам нужно будет проверить наличие нулевых значений и проанализировать их соответственно:

private String optString_1(final JSONObject json, final String key) {
    return json.isNull(key) ? null : json.optString(key);
}

2) Не отправляйте ключи с нулевыми значениями и используйте optString (key, null) напрямую (это позволит вам сэкономить пропускную способность).

{
"street2": "s2",
"province": "p1"
}
23
dev.serghini
if (json != null && json.getString(KEY_SUCCESS) != null){
     // PARSE RESULT 
}else{
    // SHOW NOTIFICIATION: URL/SERVER NOT REACHABLE

}

это для проверки JSON NULL с ключом Word.

JSONObject json = new JSONObject("{\"hello\":null}");
json.getString("hello");

это вы получите String "NULL", а не NULL.

твое громкое использование

if(json.isNull("hello")) {
    helloStr = null;
} else {
    helloStr = json.getString("hello");
}

сначала проверьте с помощью isNull () .... если не получается, попробуйте ниже

а также у вас есть JSONObject.NULL для проверки нулевого значения ...

 if ((resultObject.has("username")
    && null != resultObject.getString("username")
    && resultObject.getString("username").trim().length() != 0)
    {
           //not null
    }

а в твоем случае тоже проверь 

resultObject.getString("username").trim().eqauls("null")

Если вы должны сначала проанализировать json, а потом обработать объект, попробуйте

Синтаксический анализатор

Object data = json.get("username");

Укротитель

 if (data instanceof Integer || data instanceof Double || data instanceof Long) {
        // handle number ;
  } else if (data instanceof String) {
        // hanle string;               
  } else if (data == JSONObject.NULL) {
        // hanle null;                 
  }
0
bhanu Prakash Dave

Избавиться от этой ситуации, просто заменив "null" на "".

String city = address.optString("city").replace("null", "");
0
Sunit Kumar Samanta

Мой анализатор Josn был длинным и должен был создать новый класс, чтобы это исправить, Затем просто нужно было добавить 1 дополнительную строку в каждый метод и переименовать текущее имя свойства JSONObject, поэтому все остальные вызовы ссылались на мой новый класс вместо JSONObject , 

    public static ArrayList<PieceOfNews> readNews(String json) {
    if (json != null) {
        ArrayList<PieceOfNews> res = new ArrayList<>();
        try {
            JSONArray jsonArray = new JSONArray(json);
            for (int i = 0; i < jsonArray.length(); i++) {
                //before JSONObject jo = jsonArray.getJSONObject(i);
                JSONObject joClassic = jsonArray.getJSONObject(i);
                //facade
                FixJsonObject jo = new FixJsonObject(joClassic);
                PieceOfNews pn = new PieceOfNews();
                pn.setId(jo.getInt("id"));
                pn.setImageUrl(jo.getString("imageURL"));
                pn.setText(jo.getString("text"));
                pn.setTitle(jo.getString("title"));
                pn.setDate(jo.getLong("mills"));
                res.add(pn);
            }
            return res;
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    return null;
}

Вот мой класс с методами, которые мне нужны, вы можете добавить больше

public class FixJsonObject {
private JSONObject jsonObject;

public FixJsonObject(JSONObject jsonObject) {
    this.jsonObject = jsonObject;
}

public String optString(String key, String defaultValue) {
    if (jsonObject.isNull(key)) {
        return null;
    } else {
        return jsonObject.optString(key, defaultValue);
    }
}

public String optString(String key) {
    return optString(key, null);
}

public int optInt(String key) {
    if (jsonObject.isNull(key)) {
        return 0;
    } else {
        return jsonObject.optInt(key, 0);
    }
}

public double optDouble(String key) {
    return optDouble(key, 0);
}

public double optDouble(String key, double defaultValue) {
    if (jsonObject.isNull(key)) {
        return 0;
    } else {
        return jsonObject.optDouble(key, defaultValue);
    }
}

public boolean optBoolean(String key, boolean defaultValue) {
    if (jsonObject.isNull(key)) {
        return false;
    } else {
        return jsonObject.optBoolean(key, defaultValue);
    }
}

public long optLong(String key) {
    if (jsonObject.isNull(key)) {
        return 0;
    } else {
        return jsonObject.optLong(key, 0);
    }
}

public long getLong(String key) {
    return optLong(key);
}

public String getString(String key) {
    return optString(key);
}

public int getInt(String key) {
    return optInt(key);
}

public double getDouble(String key) {
    return optDouble(key);
}

public JSONArray getJSONArray(String key) {
    if (jsonObject.isNull(key)) {
        return null;
    } else {
        return jsonObject.optJSONArray(key);
    }
}

}

0
Galeen

Если значения для ключа равны нулю, как показано ниже 

{

  "status": 200,

  "message": "",

  "data": {

    "totalFare": null,
  },

}

check with "isNull" , for Eg:

String strTotalFare;

if (objResponse.isNull("totalFare")) 

{

  strTotalFare = "0";

} else {

 strTotalFare = objResponse.getString("totalFare");

}

если значение равно «null» для ключа «totalFare», вышеуказанная функция войдет в if и присвоит значение ноль, иначе получит фактическое значение из ключа.

0
Digvijay Machale

Используя в качестве основы ответ Мэтта Куигли, вот код, если вы хотите имитировать полную функциональность optString, включая запасную часть, написанную на Kotlin и Java. 

Котлин:

fun optString(json: JSONObject, key: String, fallback: String?): String? {
    var stringToReturn = fallback
    if (!json.isNull(key)) {
        stringToReturn = json.optString(key, null)
    }
    return stringToReturn
}

Джава:

public static String optString(JSONObject json, String key, String fallback) {
    String stringToReturn = fallback;
    if (!json.isNull(key)) {
        stringToReturn = json.optString(key, null);
    }
    return stringToReturn;
 }

Просто введите значение NULL для параметра возврата, если вам не нужен запасной вариант.

0
Bret Smith