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
сделает именно то, что я ожидал. Кто-нибудь знает, что здесь происходит не так?
Ответы
Ответ 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", "");