【问题标题】:Android - Validating JSON when getting a response from a server to avoid a JSONExceptionAndroid - 在从服务器获取响应时验证 JSON 以避免 JSONException
【发布时间】:2012-06-13 11:56:41
【问题描述】:

在我的一些与服务器通信并使用 http 获得响应的应用程序中,我使用 json 来格式化数据服务器端,当它到达设备时,我使用类似于我在 stackoverflow 上找到的代码:

private class LoadData extends AsyncTask<Void, Void, String> 
{ 
private  JSONArray jArray;
private  String result = null;
private  InputStream is = null;
private String entered_food_name=choice.getText().toString().trim();
protected void onPreExecute() 
{
}

@Override
protected String doInBackground(Void... params) 
{
try {
ArrayList<NameValuePair> nameValuePairs = new            ArrayList<NameValuePair>();
HttpClient httpclient = new DefaultHttpClient(); 
HttpPost httppost = new HttpPost("http://10.0.2.2/food.php");
nameValuePairs.add(new BasicNameValuePair("Name",entered_food_name));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,"UTF-8"));
HttpResponse response = httpclient.execute(httppost);

HttpEntity entity = response.getEntity();
 is = entity.getContent();

    //convert response to string

BufferedReader reader = new BufferedReader(new InputStreamReader(is,"utf-8"),8);
    StringBuilder sb = new StringBuilder();
    String line = null;
    while ((line = reader.readLine()) != null) {
        sb.append(line);
    }

    is.close();


    result =sb.toString();
    result = result.replace('\"', '\'').trim();

}
catch(Exception e){
    Log.e("log_tag", " connection" + e.toString());                     
}


return result;  

}

@Override
protected void onPostExecute(String result) 
{  
try{

    String foodName="";
    int Description=0;

    jArray = new JSONArray(result); // here if the result is null an exeption will occur
    JSONObject json_data = null;

    for (int i = 0; i < jArray.length(); i++) {
        json_data = jArray.getJSONObject(i);
        foodName=json_data.getString("Name");
        .
        .
        .
        .
        .
    } 
    catch(JSONException e){ 
        **// what i can do here to prevent my app from crash and 
        //  make toast " the entered food isnot available " ????**
        Log.e("log_tag", "parssing  error " + e.toString()); 
    }   
}
}

我尝试使用找到此代码的页面上的解决方案。顺便说一下链接How do I prevent my app from crashing unexpectedly, "force close", when using JSON data, and handle the exception instead?

我尝试使用在线验证器检查我的 json 响应,返回的 json 是有效的。我认为当用户处于覆盖范围较差的区域时,连接会暂时中断或某些原因导致 json 被破坏,从而导致 json 异常,即使我已经尝试了我在该链接中发布的线程中建议的方法。因此,我希望能够在 JSON 到达手机时对其进行验证,因此如果它有效,我可以继续,如果不是,我想尝试修复它,或者至少不尝试传递损坏且格式不正确的 json数组到导致 JSONException 的方法之一。

关于验证我在响应中得到的字符串以确保其有效的 JSON 的任何提示都很棒。

编辑:添加了与问题相关的堆栈转储

org.json.JSONException: Value null at results of type org.json.JSONObject$1 cannot be     converted to JSONArray
at org.json.JSON.typeMismatch(JSON.java:96)
at org.json.JSONObject.getJSONArray(JSONObject.java:548)
at it.cores.Activity$GetM.doInBackground(Activity.java:1159)
at it.cores.Activity$GetM.doInBackground(Activity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)

【问题讨论】:

  • 假设您将 JSONArray 实例包装在 try catch 块中,那么您不是在保护您的应用程序免于强制关闭吗?您需要做的就是在使用之前检查jArray 是否为空。通过使用包含在字符串中的 JSON 数据来实例化 JSONArray,将是一种验证形式,否则它将无法实例化。
  • 返回的响应字符串永远不会为空。正在发生的事情是 JSON 有时会以某种方式被破坏。我无法重现我在崩溃存储库中看到的错误,但是从堆栈转储中我可以看到它是由 org.json.JSONException 引起的: org.json.JSONObject$1 类型的结果中的值 null 无法转换为 JSONArray 并且在尝试捕捉。
  • 从我读过的所有内容中,当您尝试解析损坏或格式不正确的 json 时,您将得到该异常
  • 我编写了一个处理来自 Web 服务的 JSON 数据的应用程序,但我从未见过 JSONException 转义 catch 子句。你确定你正确地解释了堆栈转储吗?前面的评论听起来就像您正在阅读 catch 子句中的 log 方法调用的输出。您可以发布堆栈跟踪的相关部分吗?
  • 当然,但是当我的应用程序崩溃时,我使用 ACRA 来捕获堆栈转储。我将转储添加到我的问题中。

标签: android json validation jsonexception


【解决方案1】:

在对字符串结果执行任何操作之前,您必须确保在执行空检查/或任何其他验证(例如检查它是否包含响应代码)之后进行解析。

protected void onPostExecute(String result) 
{  
try{

    String foodName="";
    int Description=0;

if(result!=null)//Do your validation for result

{
    jArray = new JSONArray(result); // here if the result is null an exeption will occur
    JSONObject json_data = null;

    for (int i = 0; i < jArray.length(); i++) {
        json_data = jArray.getJSONObject(i);
        foodName=json_data.getString("Name");
        .
        .
        .
        .
        .
    } 
 }
   catch(JSONException e){ 
        **// what i can do here to prevent my app from crash and 
        //  make toast " the entered food isnot available " ????**
        Log.e("log_tag", "parssing  error " + e.toString()); 
    }   
}

【讨论】:

  • 是的,暂时这就是我所做的,但我想肯定的是,当 json 进入设备并且格式不正确时,我可以处理这种情况。我无法重现某些人似乎“在野外”出现的错误。你知道吗,我可以在 JSON 到达设备后验证我的 JSON,结果字符串不为空。
  • 如果您可以检查从服务器获得的响应代码(例如成功的一些 200)以及空值检查,那就太好了
  • 问题不是来自服务器的响应,它对我来说就像预期的那样返回。问题似乎是在网络条件不佳的情况下,json 会以某种方式被破坏,因为它的格式不再正确,所以我得到 JSONException。
  • @donfuxx 我也有类似的问题,也许你能帮我,看我的帖子:stackoverflow.com/questions/38030215/…
猜你喜欢
  • 2015-09-27
  • 1970-01-01
  • 1970-01-01
  • 2016-03-12
  • 2019-02-03
  • 1970-01-01
  • 1970-01-01
  • 2021-02-07
  • 1970-01-01
相关资源
最近更新 更多