JSON jsonObject.optString() 返回字符串“null”

Posted

技术标签:

【中文标题】JSON jsonObject.optString() 返回字符串“null”【英文标题】:JSON jsonObject.optString() returns String "null" 【发布时间】:2013-08-16 02:01:17 【问题描述】:

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

这是我来自服务器的 json


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

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

我在 Google 或 *** 上找不到任何关于此问题的信息。我真的不明白它是如何发生的,因为我认为optString 会完全符合我的预期。有人知道这里出了什么问题吗?

【问题讨论】:

null 是 java 中字符串的有效值(以及我知道的所有其他编程语言),所以它不选择后备是有道理的,如果它的键根本不存在,它会采取后备措施 谢谢。这不是我对 optString 的预期行为,但开发人员似乎有不同的想法。必须自己检查。 【参考方案1】:

遇到这个问题并挠头想“他们真的是这个意思吗?”的不止你一个人。根据 AOSP 问题,Google 工程师确实 认为这是一个错误,但他们必须与 org.json 实现兼容,即使错误兼容。

如果您考虑一下,这是有道理的,因为如果使用相同库的相同代码在其他 Java 环境中运行时在 Android 中的行为不同,则在使用 3rd 方库时会出现严重的兼容性问题。即使意图是好的并且它确实修复了错误,它也会打开一个全新的蠕虫罐。

根据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);

【讨论】:

为什么在您的自定义方法中调用json.optString(key, null) 而不仅仅是json.getString(key) 辅助方法是optString 的替代品,而不是getStringopt 表示可选,如果key不存在不会抛出异常。【参考方案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"

【讨论】:

+1 for json.isNull(key),导致 if(json.get(key) == null) 无法正常工作 注意:如果找不到密钥,json.optString(key) 将返回一个空字符串。【参考方案3】:

只需将"null" 替换为"",即可摆脱这种情况。

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

【讨论】:

简单而合乎逻辑;) 希望没有包含字符序列'null'的城市【参考方案4】:

使用 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

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。

【讨论】:

【参考方案5】:
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" not 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;                 
  

【讨论】:

【参考方案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】:

如果 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 并赋值为零,否则它将从键中获取实际值。

【讨论】:

【参考方案8】:

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

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;
    

【讨论】:

【参考方案9】:

我喜欢这样...

String value; 

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

      

【讨论】:

以上是关于JSON jsonObject.optString() 返回字符串“null”的主要内容,如果未能解决你的问题,请参考以下文章

JSONObject optString

JSONObject optString或者getString方法取null问题

mysql json 方法

python中json文件处理涉及的四个函数json.dumps()和json.loads()json.dump()和json.load()的区分

json数据和json数组格式数据的区别

JSON相关 JSON在线解析 JSON压缩转义工具 JSON着色工具 JSON 在线格式化工具 在线XML/JSON互相转换工具 XMLJSON在线转换