Google Gson обрабатывает каждый локальный файл JSON как строку, даже если его нет

#java #json #gson #jsonparser

#java #json #io #gson #json-десериализация

Вопрос:

Я постоянно получаю Expected BEGIN_TYPE but was STRING at line 1 column 1 path $ ошибку. Я читал об этой ошибке, но я испытываю что-то другое.

Когда я пытаюсь использовать gson.fromJson() JSON строку, которую я создал в своем приложении, она компилируется нормально.

      ArrayList<MyCar> cars = new ArrayList<>();
     cars.add(new MyCar());
     cars.add(new MyCar());
     String json = gson.toJson(cars);
  

Это компилируется.

      Type carList = new TypeToken<ArrayList<MyCar>>(){}.getType();
     ArrayList<MyCar> myCars = gson.fromJson(json, carList); 
  

Это также компилируется.

Моя проблема заключается в том, что я пытаюсь прочитать из локального файла, который я либо написал сам, либо скачал из Интернета (я запустил все локальные файлы JsonLint , и они действительны).

Вот JSON при записи в файл с именем testingArray.json :

 [{
    "model": "I3",
    "manufacturer": "Audi",
    "features": ["wifi", "bluetooth", "charging"]
}, {
    "model": "I3",
    "manufacturer": "Audi",
    "features": ["wifi", "bluetooth", "charging"]
}, {
    "model": "I3",
    "manufacturer": "Audi",
    "features": ["wifi", "bluetooth", "charging"]
}]
  

Он явно начинается со скобок, а не с кавычек.

Но это:

  Type carList = new TypeToken<ArrayList<MyCar>>(){}.getType();
 ArrayList<MyCar> myCars = gson.fromJson(basePath   "testingArray.json", carList); 
  

Не компилируется и выдает вышеупомянутую ошибку.

Я ошеломлен, почему, потому что, когда я запускаю fromJson POJO like JSON , это работает. Но если я запускаю ТЕ ЖЕ данные JSON из локального файла, это не работает. Он всегда считывает его как строку, даже если он начинается со скобок.

Ответ №1:

Путь к файлу обрабатывается буквально как JSON полезная нагрузка, поэтому вы видите это исключение. Вам необходимо создать Reader на основе пути к файлу:

 try (FileReader jsonReader = new FileReader(basePath   "testingArray.json")) {
    Type carList = new TypeToken<ArrayList<MyCar>>(){}.getType();
    List<MyCar> myCars = gson.fromJson(jsonReader, carList); 
}
  

Комментарии:

1. Это работает! И есть ли причина, по которой GSON требует, чтобы вы переносили путь в FileReader, а Джексон этого не делает?

2. @Fletcher, это из-за перегрузки метода . Когда вы предоставляете String переменную Gson , она обрабатывается как необработанная JSON . Если вы хотите предоставить JSON из файла или другого источника, который вам необходимо использовать Reader , чтобы было ясно, что stream его следует использовать.