无外层数组名时,如何直接解析JSON中的likes与webformatURL字段?
处理两种JSON格式的兼容解析方案
很典型的接口格式兼容问题!你的现有代码只适配了返回带hits数组的JSON对象,但要兼容根节点直接是数组的情况,我们需要先判断返回数据的类型,再分别处理。
核心思路
因为Volley的JsonObjectRequest会强制要求返回的是JSON对象,如果返回数组会直接触发错误回调,所以我们可以改用StringRequest先获取原始响应字符串,再手动解析判断是对象还是数组:
- 拿到响应字符串后,先尝试解析为
JSONObject,如果成功就按原来的逻辑取hits数组 - 如果解析对象失败,再尝试解析为
JSONArray,直接遍历这个数组提取字段
修改后的代码示例
private void parseJSON() { String url = "https://pixabay.com/api/?key=8947271-cb39739eaa5835e1eaa2f53c6&q=yellow+flowers&image_type=photo&pretty=true"; StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { try { // 先判断是否为JSON对象格式 if (response.startsWith("{")) { JSONObject jsonObject = new JSONObject(response); JSONArray jsonArray = jsonObject.getJSONArray("hits"); extractDataFromArray(jsonArray); } // 再判断是否为JSON数组格式 else if (response.startsWith("[")) { JSONArray jsonArray = new JSONArray(response); extractDataFromArray(jsonArray); } } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { error.printStackTrace(); } } ); // 记得将请求加入Volley请求队列(若之前未添加) // RequestQueue queue = Volley.newRequestQueue(this); // queue.add(request); } // 抽离数组数据提取逻辑,避免重复代码 private void extractDataFromArray(JSONArray jsonArray) throws JSONException { for (int i = 0; i < jsonArray.length(); i++) { JSONObject hit = jsonArray.getJSONObject(i); // 可以添加字段存在性判断,避免字段缺失导致崩溃 String imageUrl = hit.has("webformatURL") ? hit.getString("webformatURL") : ""; int likeCount = hit.has("likes") ? hit.getInt("likes") : 0; mExampleList.add(new ExampleItem(imageUrl, likeCount)); } mExampleAdapter = new ExampleAdapter(MainActivity.this, mExampleList); mRecyclerView.setAdapter(mExampleAdapter); }
关键细节说明
- 用
response.startsWith()快速判断根节点类型,比直接捕获解析异常更高效 - 把数组遍历逻辑抽成独立方法,让代码更简洁易维护
- 新增了
has()方法检查字段是否存在,避免因接口返回字段缺失导致的崩溃
内容的提问来源于stack exchange,提问作者Jasur Kurbanov
相关产品推荐
相关产品推荐

