【问题标题】:Advoid many try-catch blog when parse json解析json时避免很多try-catch博客
【发布时间】:2016-01-22 03:44:42
【问题描述】:

我尝试从 Facebook sdk 获取数据:

public void onCompleted(JSONObject object, GraphResponse response) {
    String name = null;
    try {
        name = object.getString("name");
    } catch (JSONException e) {
        e.printStackTrace();
    }
    String profile = null;
    try {
        profile = object.getJSONObject("picture").getJSONObject("data").getString("url");
    } catch (JSONException e) {
        e.printStackTrace();
    }
    String cover = null;
    try {
        cover = object.getJSONObject("cover").getString("source");
    } catch (JSONException e) {
        e.printStackTrace();
    }
    String email = null;
    try {
        email = object.getString("email");
    } catch (JSONException e) {
        e.printStackTrace();
    }
    String gender = null;
    try {
        gender = object.getString("gender");
    } catch (JSONException e) {
        e.printStackTrace();
    }
    String birthday = null;
    try {
        birthday = object.getString("birthday");
    } catch (JSONException e) {
        e.printStackTrace();
    }
    new SessionManager(activity).storeUserInfo(name, profile, cover, email, gender, birthday);
}

非常不利,因为有很多字段,每个字段都可以为空,每个字段都需要一个try-cach博客。

我需要一个解决方案来更清晰地呈现代码。

【问题讨论】:

  • 每个字段都可以为空 ???当object.getString("key"); 返回 null 时,你的捕获发生了,对吗???
  • 如果没有“key”,它会抛出一个异常,所以我需要捕获它以避免传递其他字段
  • 不,它会抛出异常
  • 您不能使用 Gson 或 Jackson 吗?这已经是一个已解决的问题。
  • @mdtuyen 好的,检查我的答案

标签: android json exception


【解决方案1】:

如果您只想删除 try catch 块,请使用“opt”替换“get” (例如optInt(Key)optString(Key) ..)

请注意,如果键不存在,“opt”将返回null,它可能会出现许多空指针异常而不检查。

【讨论】:

  • OP 在许多情况下已经有空值(无论是否有意),因此使用 optXYZ 是避免单个键上出现异常的最直接方法。
  • 我认为在这种情况下最好使用 gson。
【解决方案2】:

好的,您可以通过调用object.has("key") 来检查密钥是否存在,如下所示:

public void onCompleted(JSONObject object, GraphResponse response) {
    String name = "", profile = "", cover = "", email = "", gender = "", birthday = "";
    try {
        if (object.has("name")){
            name = object.getString("name");
        }
        if (object.has("picture")){
            profile = object.getJSONObject("picture").getJSONObject("data").getString("url");
        }
        if (object.has("cover")){
            cover = object.getJSONObject("cover").getString("source");
        }
        if (object.has("email")){
            email = object.getString("email");
        }
        if (object.has("gender")){
            gender = object.getString("gender");
        }
        if (object.has("birthday")){
            birthday = object.getString("birthday");
        }

    } catch (JSONException e) {
        e.printStackTrace();
    }
    new SessionManager(activity).storeUserInfo(name, profile, cover, email, gender, birthday);
}

【讨论】:

  • 说 object.getString("name") 抛出 NPE,你将永远无法达到其余的值。对吗?
  • 比较清晰但还是比较长,我会考虑作为一个选项。
  • object.has("name") 是检查name 是否存在,如果不存在,name = object.getString("name"); 将永远不会调用,那么如何发生NPE @Jiyeh
  • 是的,但是如果 .getJSONObject("data") 抛出 null,你也必须检查一下
  • @meda 是的,但在这种情况下,函数 onCompleted 已经有 objectJSONObject ,我们不再需要 .getJSONObject("data")
【解决方案3】:

我宁愿这样做:

String value = object.has(key) && !object.isNull(key) ? object.getString(key) : null;

一行,更干净更简单~:)

【讨论】:

  • 如果使用这种格式的代码超过 .. 一次,我宁愿“编写一个方法”。
  • 是的,你可以!它使它更清洁。
【解决方案4】:

将所有语法添加到一个 try 块中如果任何一种语法有异常而不是 go in catch....

public void onCompleted(JSONObject object, GraphResponse response) { String name = null; try { name = object.getString("name"); String profile = null; profile = object.getJSONObject("picture").getJSONObject("data").getString("url"); String cover = null; cover = object.getJSONObject("cover").getString("source"); String email = null; email = object.getString("email"); String gender = null; gender = object.getString("gender"); String birthday = null; birthday = object.getString("birthday"); } catch (JSONException e) { e.printStackTrace(); } new SessionManager(activity).storeUserInfo(name, profile, cover, email, gender, birthday); }

【讨论】:

  • (代码缩进4个空格,除非想创建标题,否则避免使用'---'的行。您可以返回并添加换行符。)
  • 如果缺少关键字“电子邮件”会发生什么,我们无法获取性别和生日。
【解决方案5】:

所有字段都是必填的吗?
你可以这样做:

try{
   name = object.getString("name");
   ... // more methods here
   new SessionManager(activity).storeUserInfo(name, profile, cover, email, gender, birthday);
}catch(JSONException e){
  e.printStackTrace( );
}  

这样,只有在您检索到所有字段后,您才会到达SessionManager。即使缺少一个字段,您也将直接进入catch 块。

其他:

public String getString(JSONObject obj,String key,String defVal){
    if( obj.has(key) )
        return obj.getString( key );
    return defVal; 
}  

现在你可以这样做:

name = getString(json,"name","UNDEFINED");

【讨论】:

  • 如果缺少关键字“电子邮件”会发生什么,我们无法获取性别和生日。
猜你喜欢
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
  • 1970-01-01
  • 2011-12-09
相关资源
最近更新 更多