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

我正在开发一个 Android 应用程序,它使用 JSON 进行服务器通信,当我试图解析我的 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 检查将返回 false。如果我调用 address.isNull("city"),它返回 true,这是正确的。只有 optString失败了。

我在 Google 或 Stackoverflow 上找不到任何关于这个问题的信息。我真的不明白这是怎么发生的,因为我认为 optString会做的正是我所期望的。有人知道这里出了什么问题吗?

63757 次浏览

你基本上有两个选择:

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)不要发送带有 null 值的键,直接使用 optString (key,null)(应该可以节省带宽)。

{
"street2": "s2",
"province": "p1"
}

并不是只有你一个人碰到这个问题就会抓头发,想着“他们真的是这个意思吗?”根据一个 AOSP 问题,谷歌工程师 强大 就当这是个窃听器吧,但他们必须与 org.json 实现兼容,甚至 bug 兼容。

如果你仔细想想,这是有道理的,因为如果在其他 Java 环境中使用相同库的相同代码在 Android 中表现不同,那么在使用第三方库时将会出现严重的兼容性问题。即使意图是好的,它真的修复了 bug,它也会打开一个全新的蠕虫罐头。

根据 AOSP 问题:

这种行为是有意为之的; 我们特意做到了与 org.json 兼容 bug。现在这个问题已经解决了,我们还不清楚是否应该修复我们的代码。应用程序可能已经开始依赖于这种错误行为。

如果这使您感到不安,我建议您使用不同的机制来测试 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);
}
if (json != null && json.getString(KEY_SUCCESS) != null){
// PARSE RESULT
}else{
// SHOW NOTIFICIATION: URL/SERVER NOT REACHABLE

}

那是用 there 关键字检查 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 ()检查... ... 如果不能工作,那么尝试下面的方法

还有 JSONObject.NULL 来检查 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;
}

如果键值为空,如下所示

{


"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”,则上面的函数将输入 if 并赋值为零,否则它将从 key 获得实际值。

如果您希望模仿 optString 的完整功能,包括用 Kotlin 和 Java 编写的回退部分,那么以 Matt Quigley 的回答为基础,下面是代码。

科特林:

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。

我的 Josn 解析器很长,必须创建一个新类来修复它, 然后只需在每个方法中额外添加一行,并重命名当前 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);
}
}

}

通过简单地用 ""代替 "null",摆脱了这种情况。

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

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

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

我喜欢这样。

String value;


if(jsonObject.get("name").toString().equals("null")) {
value = "";
}else {
value = jsonObject.getString("name");
}