Android - 如何从字符串中解析JsonArray?

9

我正在尝试从JSON字符串中解析JSON数组,但它总是抛出异常data of type java.lang.String cannot be converted to JSONArray

请告诉我是否犯了任何错误。

谢谢。

以下是从服务器获取Json的代码:

try {
                String url = String.format(<url here>, province.provinceCode2);
                HttpClient httpClient = getHttpClient();
                HttpGet httpGet = new HttpGet(url);
                HttpResponse httpResponse = httpClient.execute(httpGet);
                HttpEntity entity = httpResponse.getEntity();
                final String result = EntityUtils.toString(entity);
                parseAndSaveJsonData(province, result);
            } catch (Exception e) {
                e.printStackTrace();
            }

这里有解析Json数组的代码:
String jsonString = <below json string>
JSONArray ja = new JSONArray(jsonString);

这是我的JSON字符串:

   [
   {
      "LotPrizes":[
         {
            "Prize":"Giảitám",
            "Range":"50"
         },
         {
            "Prize":"Giảibảy",
            "Range":"264"
         },
         {
            "Prize":"Giảisáu",
            "Range":"3654-5162-3097"
         },
         {
            "Prize":"Giảinăm",
            "Range":"9739"
         },
         {
            "Prize":"Giảitư",
            "Range":"97690-99274-32442-69432-04855-10132-17085"
         },
         {
            "Prize":"Giảiba",
            "Range":"73745-13007"
         },
         {
            "Prize":"Giảinhì",
            "Range":"05521"
         },
         {
            "Prize":"Giảinhất",
            "Range":"74870"
         },
         {
            "Prize":"GiảiDB6",
            "Range":"878833"
         }
      ]
      },
 {
      "LotPrizes":[
         {
            "Prize":"Giảitám",
            "Range":"50"
         },
         {
            "Prize":"Giảibảy",
            "Range":"264"
         },
         {
            "Prize":"Giảisáu",
            "Range":"3654-5162-3097"
         },
         {
            "Prize":"Giảinăm",
            "Range":"9739"
         },
         {
            "Prize":"Giảitư",
            "Range":"97690-99274-32442-69432-04855-10132-17085"
         },
         {
            "Prize":"Giảiba",
            "Range":"73745-13007"
         },
         {
            "Prize":"Giảinhì",
            "Range":"05521"
         },
         {
            "Prize":"Giảinhất",
            "Range":"74870"
         },
         {
            "Prize":"GiảiDB6",
            "Range":"878833"
         }
      ]
      }

    ]

你能展示一下从服务器获取字符串的代码吗? - ρяσѕρєя K
这是一个 JSON “对象”,而不是一个“数组”。不幸的是,有些(脑残)JSON API 坚持要求您在解析之前知道它是一个对象还是一个数组,因此有时您必须查看第一个字符是否为“{”或“[”。 - Hot Licks
我将字符串更改为“继续与Caerulius讨论”。原始字符串被包含在[ ]中。 - Nguyen Minh Binh
@ρяσѕρєя K,请查看我的更新,获取从服务器获取JsonString的源代码。 - Nguyen Minh Binh
我终于找到了根本原因。请看我的回答。我认为这是HttpEntity的一个bug。 - Nguyen Minh Binh
显示剩余3条评论
3个回答

18

这是初始化JSON解析器的方法:

JSONObject jsonObject = new JSONObject(jsonString);

这将给你整个字符串作为一个 JSON 对象。从那里,像这样提取单个数组作为 JsonArray:

JSONArray jsonArray = jsonObject.getJSONArray("LotPrizes");

要访问每个“LotPrizes”,您可以使用for循环逻辑:

for(int i=0;i<jsonArray.length();i++)
{
  JSONObject curr = jsonArray.getJSONObject(i);

  prize = curr.getString("Prize")

//Do stuff with the Prize String here
//Add it to a list, print it out, etc.
}

编辑: 根据您的JSON编辑,最终代码如下:

JSONArray jsonArray = null;
String jsonString = <your string>
String currPrize = null;

JSONObject jsonObject = new JSONObject(jsonString);

jsonArray = jsonObject.getJSONArray("data");

for(int i=0;i<jsonArray.length();i++)
{
    JSONArray currLot = jsonArray.getJSONObject(i);

    for(int j=0; j<currLot.length();j++)
    {
        JSONobject curr = currLot.getJSONObject(j);

        currPrize = curr.getString("Prize");

        //Do something with Prize
    }
}

这段代码是可用的,我在我的代码中使用了几乎相同版本的代码。希望这次可以解决问题。


1
但是,如何获取“LotPrizes”数组的父JsonObject?在我的字符串中,这个JsonArray有2个项。 - Nguyen Minh Binh
1
基本上,你的主要问题在于你无法用一个字符串初始化JSONArray。你必须先将其创建为JSONObject,然后从中获取JSONArray。 - Caerulius
当我尝试使用您的解决方案时,出现了一个新的异常:“没有“LotPrizes”的值”。这是因为“LotPrizes”是根JsonObject的grandChild。您可以将我的json粘贴到http://jsonparser.com/上查看它。根Json数组有2个项目,我想获取这2个项目。 - Nguyen Minh Binh
这似乎是您的JSON格式问题。您有空的根节点连接到子节点。我猜想你正在创建自己的JSON字符串,如果是这样,请阅读关于JSON格式的信息以创建正确的JSON字符串。http://www.w3schools.com/json/default.asp - Caerulius
不,我不认为我的Json字符串语法有问题。因为http://jsonparser.com/可以很好地解析它。你有什么想法吗? - Nguyen Minh Binh
显示剩余8条评论

2
您可以按照以下方式从字符串中检索json数据..
            JSONObject json = new JSONObject(jsonString);
            JSONArray jData = json.getJSONArray("data");
            for (int i = 0; i < jData.length(); i++) {
                JSONObject jo = jData.getJSONObject(i);

                JSONArray jLotPrizes = jo.getJSONArray("LotPrizes");
                for (int j = 0; j < jLotPrizes.length(); j++) {
                    JSONObject jobj = jLotPrizes.getJSONObject(j);

                    Log.i("Prize", "" + jobj.getString("Prize"));
                    Log.i("Range", "" + jobj.getString("Range"));
                }

            }

2

大家好,@Caerulius、Harish、ρяσѕρєя K、Hot Licks等。经过两天的头痛和两个不眠之夜,我终于解决了问题。因为你们花费了宝贵的时间与我讨论,所以我认为我有责任告诉你们问题的根本原因。

首先,我是一名资深的Android开发者。因此,我至少了解JSON的基础知识,知道如何从JSON字符串中解析数据,并且我知道许多有用的在线工具来验证它。我确认从服务器获取的JSON字符串是有效的。

正如我在问题中所说,我使用final String result = EntityUtils.toString(entity);HttpEntity对象中获取JSON字符串。我以前多次使用这个方法,都没有问题。但是,在这种情况下,它不起作用了。原始的JSON字符串如下:

   [{
      "LotPrizes":[
         {
            "Prize":"Giảitám",
            "Range":"50"
         },
         {
            "Prize":"Giảibảy",
            "Range":"264"
         },
         ...
    }]

但我得到的结果是这样的:
"[{
      \"LotPrizes\":[
         {
            \"Prize":\"Giảitám\",
            \"Range\":\"50\"
         },
         {
            \"Prize\":\"Giảibảy\",
            \"Range\":\"264\"
         },
         ...
    }]"

这个字符串与我们可以声明的常量字符串类似,如下所示:

String stringVariable = "\"[{
          \\\"LotPrizes\\\":[
             {
                \\\"Prize":\\\"Giảitám\\\",
                \\\"Range\\\":\\\"50\\\"
             },
             {
                \\\"Prize\\\":\\\"Giảibảy\\\",
                \\\"Range\\\":\\\"264\\\"
             },
             ...
        }]\" ;

这是一个有效的字符串,但不是有效的JSON字符串。

为了解决这个问题,我改变了获取JSON字符串的方式,并删除了不必要的字符,就像这样:

                            HttpClient httpClient = getHttpClient();
                HttpGet httpGet = new HttpGet(url);
                HttpResponse httpResponse = httpClient.execute(httpGet);
                HttpEntity entity = httpResponse.getEntity();
                InputStream is = entity.getContent();
                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 + "\n");
                }
                is.close();
                String json = sb.toString();

                json = json.replace("\\", "");
                json = json.substring(1);
                json = json.substring(0, json.length() - 2);

现在,json变量包含JSON字符串,我可以正确解析。我认为这应该是HttpEntity库的一个错误。
希望这能帮助其他人。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接