使用Gson映射JSON报错Expected BEGIN_OBJECT but was BEGIN_ARRAY如何解决
问题诊断
你遇到的报错核心原因是JSON结构与解析目标类型不匹配:你调用的接口返回的JSON最外层是数组结构(以[]包裹多组数据),但你代码中尝试将其直接解析为单个HistoryDollarResponse对象(对应JSON对象结构,以{}包裹),Gson在预期读取对象起始符{时读到了数组起始符[,因此抛出Expected BEGIN_OBJECT but was BEGIN_ARRAY异常。
你定义的HistoryDollarResponse映射类本身没有问题,Gson会自动忽略JSON中你未声明的多余字段,不需要调整。
修改方案
你可以根据业务需求选择以下两种方案:
方案1:解析为汇率列表(推荐)
如果需要使用返回的多组历史汇率数据,调整方法返回值为List<HistoryDollarResponse>,同时借助Gson的TypeToken完成泛型集合的解析:
// 顶部新增导入 import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; import java.util.List; // 修改方法返回值和解析逻辑 public List<HistoryDollarResponse> getHistoryDollarPrice(String day, String month, String year) throws Exception { try { PropertiesLoader.load(); String date = year + month + day; String serviceUrl = PropertiesLoader.getHistoryUrl(); serviceUrl = String.format(serviceUrl, date); URL url = new URL(serviceUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); if (connection.getResponseCode() != 200) { throw new RuntimeException("HTTP error code : " + connection.getResponseCode()); } BufferedReader response = new BufferedReader(new InputStreamReader((connection.getInputStream()))); String jsonToString = Convert.jsonIntoString(response); Gson gson = new Gson(); // 声明List泛型类型 Type historyListType = new TypeToken<List<HistoryDollarResponse>>(){}.getType(); List<HistoryDollarResponse> returnList = gson.fromJson(jsonToString, historyListType); return returnList; } catch (Exception e) { e.printStackTrace(); throw new Exception("Can't access the webpage"); } }
方案2:仅取第一条数据
如果业务仅需要返回的第一条最新汇率数据,解析为列表后取第一个元素返回即可,不需要修改映射类:
// 仅修改报错行附近的解析逻辑 Gson gson = new Gson(); Type historyListType = new TypeToken<List<HistoryDollarResponse>>(){}.getType(); List<HistoryDollarResponse> tempList = gson.fromJson(jsonToString, historyListType); HistoryDollarResponse returnObject = tempList.get(0);
内容的提问来源于stack exchange,提问作者Leonardo Manzini
相关产品推荐
相关产品推荐

