JSON jsonObject.optString()返回String“null”

时间:2013-08-14 08:06:19

标签: java android json

我正在开发一个使用JSON进行服务器通信的Android应用程序,当我尝试解析我的json文件时,我遇到了一个奇怪的问题。

这是我服务器的json

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

我通过在我的地址Json-object上调用String city = address.optString("city", "")来获取City的值。对于这种情况,我期望city为空(这就是optString的用途不是吗?)但事实上它包含字符串“null”。因此,当String包含文本时,进一步的null-或isEmpty-checks将返回false。如果我调用address.isNull("city"),则返回true,这是正确的。只有optString失败。

我无法在Google或Stackoverflow上找到此问题。我真的不明白它是如何发生的,因为我认为optString会完全符合我的预期。谁知道这里出了什么问题?

9 个答案:

答案 0 :(得分:83)

你并不是唯一一个遇到这个问题并且摸不着头脑的人,在思考"他们真的有这个意思吗?"根据AOSP问题,Google工程师 认为这是一个错误,但他们必须与org.json实现兼容,甚至错误兼容。

如果您考虑一下,这是有道理的,因为如果在其他Java环境中使用相同库的相同代码在Android中表现不同,则在使用第三方库时会出现主要的兼容性问题。即使意图是好的并且它确实修复了错误,它也会开辟出一整套新的蠕虫。

根据AOSP issue

  

这种行为是有意的;我们竭尽全力与org.json兼容。既然已经修复了,我们还不清楚是否应该修复我们的代码。应用程序可能已经开始依赖这种错误行为。

     

如果这会让您感到悲伤,我建议您使用其他机制来测试null,例如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);
}

答案 1 :(得分:23)

你基本上有两个选择:

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

答案 2 :(得分:1)

通过简单地将"null"替换为"",摆脱了这种情况。

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

答案 3 :(得分:0)

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"不是空的。

你的使用

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

答案 4 :(得分:0)

如果key的值为null,则如下所示

{

  "status": 200,

  "message": "",

  "data": {

    "totalFare": null,
  },

}

check with "isNull" , for Eg:

String strTotalFare;

if (objResponse.isNull("totalFare")) 

{

  strTotalFare = "0";

} else {

 strTotalFare = objResponse.getString("totalFare");

}

如果键“totalFare”的值为“null”,则上面的函数将输入if并赋值为零,否则它将从key获得实际值。

答案 5 :(得分:0)

以Matt Quigley的答案为基础,如果你想模仿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 for fallback参数。

答案 6 :(得分:0)

我的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 :(得分:0)

我最终为此创建了一个实用程序类:

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.json.JSONException;
import org.json.JSONObject;

final public class JsonUtil {
    
    @Nullable
    public static String optString(
            @NonNull JSONObject object,
            @NonNull String key
    ) throws JSONException {
        if (object.has(key) && !object.isNull(key)) {
            return object.getString(key);
        }
        
        return null;
    }
}

答案 8 :(得分:0)

我喜欢这样...

on(trampolineExecutionContext)