有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Gson如何避免预期的BEGIN\u数组而不是BEGIN\u对象?

我使用GSON将JSON数据解析为Java,遇到了标题中所述的错误。我使用的API返回以下JSON数据:

{
  "STATUS": "SUCCESS",
  "NUM_RECORDS": "5",
  "MESSAGE": "5 records found",
  "AVAILABILITY_UPDATED_TIMESTAMP": "2015-05-03T13:59:08.541-07:00",
  "AVAILABILITY_REQUEST_TIMESTAMP": "2015-05-03T13:59:08.490-07:00",
  "AVL": [
    {
      "TYPE": "ON",
      "BFID": "205052",
      "NAME": "5th St (500-598)",
      "RATES": {
        "RS": [
          {
            "BEG": "12:00 AM",
            "END": "12:00 PM",
            "RATE": "0",
            "RQ": "No charge"
          },
          {
            "BEG": "12:00 PM",
            "END": "6:00 PM",
            "RATE": "5",
            "RQ": "Per hour"
          },
          {
            "BEG": "6:00 PM",
            "END": "12:00 AM",
            "RATE": "0",
            "RQ": "No charge"
          }
        ]
      },
      "PTS": "2",
      "LOC": "-122.4002212834,37.7776161738,-122.3989619795,37.7766113458"
    },
    {
      "TYPE": "ON",
      "BFID": "205042",
      "NAME": "5th St (450-498)",
      "RATES": {
        "RS": {
          "BEG": "12:00 AM",
          "END": "12:00 AM",
          "RATE": "0",
          "RQ": "No charge"
        }
      },
      "PTS": "2",
      "LOC": "-122.4015027158,37.7786330718,-122.4005149869,37.7778485214"
    },
  ]
}

我可以看到问题发生的地方,RS字段可以包含一个对象数组(我们称这个对象为RInfo),或者在某些情况下,它只包含一个不包含在数组中的RInfo对象。我认为发生错误是因为GSON正在查找数组,但找到了一个对象。我无法更改JSON文件的结构,因为它是由API提供的

只要RSRInfo对象的数组,我就能够成功地解析信息,但在某些情况下RS只包含一个RInfo对象,因此会发生此错误

在GSON有没有办法解决这个问题

*更新

我尝试了一个先前链接的解决方案。以下是我从该解决方案中得到的信息:

class RSDeserializer implements JsonDeserializer<RateInfo[]> {

    @Override
    public RateInfo[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException
    {


        if (json instanceof JsonArray) {
            System.out.println("fromJson in RSD:" + new Gson().fromJson(json, RateInfo[].class));
            return new Gson().fromJson(json, RateInfo[].class);
        }
        RateInfo rI = context.deserialize(json, RateInfo.class);

        return new RateInfo[] { rI };
    }

}

我还创建了一个新的GsonBuilder,如下所示

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(RateInfo[].class, new RSDeserializer());
    Gson gson = gsonBuilder.create();

似乎从未使用过自定义反序列化程序,因为从未在控制台中打印出print语句。在此之后,我尝试使用MyOBJ info = gson.fromJson(json, MyOBJ.class);反序列化json。这一行给出了预期的BEGIN_数组,但它是BEGIN_对象异常


共 (1) 个答案

  1. # 1 楼答案

    您必须更新反序列化程序,以告知您想要返回List<RateInfo>

    class RSDeserializer implements JsonDeserializer<List<RateInfo>> {
        @Override
        public List<RateInfo> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            if (json instanceof JsonArray) {
                return Arrays.asList(context.deserialize(json, RateInfo[].class));
            }
            return Collections.singletonList(context.deserialize(json, RateInfo.class));
        }
    }
    

    您还需要告诉解析器,在注册此适配器时,这也是您想要反序列化的类型:

    Type t = new TypeToken<List<RateInfo>>(){}.getType();
    Gson gson = new GsonBuilder().registerTypeAdapter(t, new RSDeserializer()).create();
    

    一个完整的工作示例可以在我的gist中找到