值类型 org.json.JSONObject 无法转换为 JSONArray
Posted
技术标签:
【中文标题】值类型 org.json.JSONObject 无法转换为 JSONArray【英文标题】:Value type org.json.JSONObject cannot be converted to JSONArray 【发布时间】:2021-07-12 13:47:56 【问题描述】:不知道我在哪里犯了错误。
代码:
public class VaccinationTotalUSA extends Fragment
RecyclerView rvRecentRecord;
ProgressBar progressBar;
private static final String TAG = VaccinationTotalUSA.class.getSimpleName();
ArrayList<VaccinationTimeline> recentRecords;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
View view = inflater.inflate(R.layout.fragment_vaccination, container, false);
// call view
rvRecentRecord = view.findViewById(R.id.vaccinationRecord);
progressBar = view.findViewById(R.id.progress_circular_vaccination);
rvRecentRecord.setLayoutManager(new LinearLayoutManager(getActivity()));
// Volley Fetch
getDataFromServer();
return view;
private void showRecyclerView()
VaccinationAdapter vaccinationAdapter = new VaccinationAdapter(recentRecords);
rvRecentRecord.setAdapter(vaccinationAdapter);
private void getDataFromServer()
String url = "https://disease.sh/v3/covid-19/vaccine/coverage/countries/USA";
recentRecords = new ArrayList<>();
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>()
@Override
public void onResponse(String response)
progressBar.setVisibility(View.GONE);
if (response != null)
Log.e(TAG, "onResponse:" + response);
try
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("timeline");
for (int i = 0; i < jsonArray.length(); i++)
JSONObject data = jsonArray.getJSONObject(i);
Iterator key = data.keys();
while (key.hasNext())
String timedata = key.next().toString();
recentRecords.add(new VaccinationTimeline(key, timedata));
showRecyclerView();
catch (JSONException e)
e.printStackTrace();
,
new Response.ErrorListener()
@Override
public void onErrorResponse(VolleyError error)
progressBar.setVisibility(View.GONE);
Log.e(TAG, "onResponse" + error);
);
Volley.newRequestQueue(getActivity()).add(stringRequest);
JSON:注意: 不能真正在时间线嵌套列表上使用 jsonObject.getString(),因为每天都会更新所有内容,即 2021 年 4 月 18 日的数据进来,3 /19/2021 将被删除
"country": "USA",
"timeline":
"3/19/21": 118313818,
"3/20/21": 121441497,
"3/21/21": 124481412,
"3/22/21": 126509736,
"3/23/21": 128217029,
"3/24/21": 130473853,
"3/25/21": 133305295,
"3/26/21": 136684688,
"3/27/21": 140180735,
"3/28/21": 143462691,
"3/29/21": 145812835,
"3/30/21": 147602345,
"3/31/21": 150273292,
"4/1/21": 153631404,
"4/2/21": 157606463,
"4/3/21": 161688422,
"4/4/21": 165053746,
"4/5/21": 167187795,
"4/6/21": 168592075,
"4/7/21": 171476655,
"4/8/21": 174879716,
"4/9/21": 178837781,
"4/10/21": 183467709,
"4/11/21": 187047131,
"4/12/21": 189692045,
"4/13/21": 192282781,
"4/14/21": 194791836,
"4/15/21": 198317040,
"4/16/21": 202282923,
"4/17/21": 202282923
我尝试了很多方法来显示这个 json 数据,有和没有迭代器。我想使用迭代器,因为我希望能够在列表中检索列表名称和数据,即 4/17/2021:1111111 错误输出:
E/VaccinationTotalUSA: onResponse:"country":"USA","timeline":"3/19/21":118313818,"3/20/21":121441497,"3/21/21":124481412,"3/22/21":126509736,"3/23/21":128217029,"3/24/21":130473853,"3/25/21":133305295,"3/26/21":136684688,"3/27/21":140180735,"3/28/21":143462691,"3/29/21":145812835,"3/30/21":147602345,"3/31/21":150273292,"4/1/21":153631404,"4/2/21":157606463,"4/3/21":161688422,"4/4/21":165053746,"4/5/21":167187795,"4/6/21":168592075,"4/7/21":171476655,"4/8/21":174879716,"4/9/21":178837781,"4/10/21":183467709,"4/11/21":187047131,"4/12/21":189692045,"4/13/21":192282781,"4/14/21":194791836,"4/15/21":198317040,"4/16/21":202282923,"4/17/21":202282923
W/System.err: org.json.JSONException: Value "country":"USA","timeline":"3\/19\/21":118313818,"3\/20\/21":121441497,"3\/21\/21":124481412,"3\/22\/21":126509736,"3\/23\/21":128217029,"3\/24\/21":130473853,"3\/25\/21":133305295,"3\/26\/21":136684688,"3\/27\/21":140180735,"3\/28\/21":143462691,"3\/29\/21":145812835,"3\/30\/21":147602345,"3\/31\/21":150273292,"4\/1\/21":153631404,"4\/2\/21":157606463,"4\/3\/21":161688422,"4\/4\/21":165053746,"4\/5\/21":167187795,"4\/6\/21":168592075,"4\/7\/21":171476655,"4\/8\/21":174879716,"4\/9\/21":178837781,"4\/10\/21":183467709,"4\/11\/21":187047131,"4\/12\/21":189692045,"4\/13\/21":192282781,"4\/14\/21":194791836,"4\/15\/21":198317040,"4\/16\/21":202282923,"4\/17\/21":202282923 of type org.json.JSONObject cannot be converted to JSONArray
at org.json.JSON.typeMismatch(JSON.java:112)
at org.json.JSONArray.<init>(JSONArray.java:96)
at org.json.JSONArray.<init>(JSONArray.java:108)
at com.programming_concept.senior_project.VaccinationTotalUSA$1.onResponse(VaccinationTotalUSA.java:83)
W/System.err: at com.programming_concept.senior_project.VaccinationTotalUSA$1.onResponse(VaccinationTotalUSA.java:69)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:82)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:29)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
【问题讨论】:
您可以考虑使用 Retrofit2,我在一个加载疫苗数据的应用程序中也使用过。您可以使用 GSONConverter 工厂对其进行私有化,以将您的数据解析为 java 对象。像魅力一样工作 【参考方案1】:该 JSON 中没有数组。在 JSON 中,数组用方括号表示([
和 ]
)。该 JSON 中没有方括号。
您有一个外部 JSON 对象,具有两个属性:country
和 timeline
。 timeline
是另一个 JSON 对象,其键基于日期和整数值。
因此,您需要修改计划以按原样使用 JSON,这意味着 JSONArray jsonArray = jsonObject.getJSONArray("timeline");
需要转换为 JSONObject timelineJson = jsonObject.getJSONObject("timeline");
。
请注意,有许多更好的适用于 Android 的 JSON 解析器,例如 Moshi。
【讨论】:
【参考方案2】:您正在尝试将“时间线”值设置为JSONArray
变量,而该值实际上是JSONObject
。这是一种可以同时检索键和值的方法:
JSONObject jsonObject = new JSONObject(response);
JSONObject subObject = jsonObject.getJSONObject("timeline");
// Separate the keys into a JSONArray
JSONArray keys = subObject.names();
// Retrieve the keys and values
for(int i=0; i < keys.length(); i++)
String key = keys.getString(i);
int value = subObject.getInt(key);
Log.d("LOG_TAG", key + " : " + value);
【讨论】:
org.json.JSONObject 无法转换为 JSONArray 问题已解决。但仍然收到错误消息(E/VaccinationTotalUSA: onResponse:"country":"USA","timeline":"3/19/21":118313818,"3/20/21":121441497,"3/21 /21":124481412, ... 4/14/21":194791836,"4/15/21":198317040,"4/16/21":202282923,"4/17/21":202282923) . 知道什么可能导致这个问题吗?因为有键和值,我需要将数组更改为 Map 吗? 它显示为错误,因为您使用Log.e()
在您的onResponse()
中打印了该消息。你有Log.e(TAG, "onResponse:" + response);
当我认为你打算放Log.d(TAG, "onResponse:" + response);
我注意到了,忘记删除我以前的 cmets。感谢您的答复。现在,我遇到了“未连接适配器,跳过布局”的问题。如果你熟悉,可以看看这个链接:***.com/questions/67149764/…。【参考方案3】:
您可以尝试以下代码。我在 Main 类本身中硬编码了 json 响应。我也使用过 ObjectMapper,它比使用 JsonObject 类好得多
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class AssessmentBridgeApplication
public static void main(String[] args) throws JsonMappingException, JsonProcessingException
String json = "\"country\":\"USA\",\"timeline\":\"3/19/21\":118313818,\"3/20/21\":121441497,\"3/21/21\":124481412,\"3/22/21\":126509736,\"3/23/21\":128217029,\"3/24/21\":130473853,\"3/25/21\":133305295,\"3/26/21\":136684688,\"3/27/21\":140180735,\"3/28/21\":143462691,\"3/29/21\":145812835,\"3/30/21\":147602345,\"3/31/21\":150273292,\"4/1/21\":153631404,\"4/2/21\":157606463,\"4/3/21\":161688422,\"4/4/21\":165053746,\"4/5/21\":167187795,\"4/6/21\":168592075,\"4/7/21\":171476655,\"4/8/21\":174879716,\"4/9/21\":178837781,\"4/10/21\":183467709,\"4/11/21\":187047131,\"4/12/21\":189692045,\"4/13/21\":192282781,\"4/14/21\":194791836,\"4/15/21\":198317040,\"4/16/21\":202282923,\"4/17/21\":202282923";
ObjectMapper mapper = new ObjectMapper();
VaccinationRecords vaccinationRecords = new VaccinationRecords();
vaccinationRecords = mapper.readValue(json, VaccinationRecords.class);
System.out.println(vaccinationRecords.getTimeline());
===========================
import java.util.Map;
public class VaccinationRecords
private String country;
Map<String, Object> timeline;
public String getCountry()
return country;
public void setCountry(String country)
this.country = country;
public Map<String, Object> getTimeline()
return timeline;
public void setTimeline(Map<String, Object> timeline)
this.timeline = timeline;
【讨论】:
以上是关于值类型 org.json.JSONObject 无法转换为 JSONArray的主要内容,如果未能解决你的问题,请参考以下文章
org.json.JSONObject & org.json.JSONArray
如何使用 ResponseEntity 返回 JSONObject 而不是 HashMap? (未找到类型返回值的转换器:类 org.json.JSONObject)
org.json.JSONObject$1 类型的值 null 无法转换为 JSONObject
未找到 Java 类型、类 org.json.JSONObject.... 和 MIME 媒体类型、application/json 的消息正文阅读器