Подтвердить что ты не робот

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

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

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

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

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

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

4b9b3361

Ответ 1

Ты не одинок, столкнувшись с этой проблемой и почесывая голову, думая: "Неужели они действительно имели в виду это?" Согласно проблеме AOSP, инженеры Google сделали , считают эту ошибку, но они должны быть совместимы с реализацией 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);
}

Ответ 2

У вас в основном есть 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"
}

Ответ 3

if (json != null && json.getString(KEY_SUCCESS) != null){
     // PARSE RESULT 
}else{
    // SHOW NOTIFICIATION: URL/SERVER NOT REACHABLE

}

который предназначен для проверки json null с ключевым словом.

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

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

использовать ваш звук

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

сначала проверьте с isNull().... если не работает, тогда попробуйте belows

а также у вас есть 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 и обработать объект, попробуйте это

Parser

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

Ответ 4

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

{

  "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 и присваивать значение ноль, иначе он получит фактическое значение от ключа.

Ответ 5

Используя ответ Мэтта Квигли в качестве основы, вот код, если вы хотите подражать полной функциональности 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
}

Java:

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 для параметра возврата, если вам не нужен резерв.

Ответ 6

Мой парсер 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);
    }
}

}

Ответ 7

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

String city = address.optString("city").replace("null", "");