Я изучаю постоянство данных, и это моя первая попытка JSON. Я прочитал несколько руководств, и из того, что я могу сказать, код был правильным в обеих попытках сохранения объектов. Я получаю файл, написанный с использованием Gson, но Gson генерирует исключения при попытке проанализировать объекты с помощью метода from Json (). У меня следующий вопрос:
- Если я использую тот же тип для преобразования в / из JSON, что мне не хватает, что скажет Gson, как правильно анализировать мой объект (ы)?
Я испробовал три разных подхода, два из которых приведены ниже. Сначала я попытался сохранить класс-обертку для списка объектов, которые, как предполагает руководство, я должен уметь делать:
public class JSONConverter {
private static Path path = Paths.get("src\\json\\JSONList.json");
private static Type stockType = new TypeToken<StocksList>(){}.getType();
public static void convertToJSON(StocksList stocks, Path path) {
Gson json = new Gson();
String storedStocks = json.toJson(stocks, stockType);// I also tried "StocksList.class" here
checkForFile(path);
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
writer.write(storedStocks);
} catch (IOException e) {
e.printStackTrace();
//handle later
}
}
static void checkForFile(Path path) {
if (Files.notExists(path)) {
try {
Files.createFile(path);
} catch (IOException e) {
e.printStackTrace();
//handle later
}
}
}
public static StocksList convertFromJSON(Path path) {
StocksList stocksList = new StocksList();
Gson json = new Gson();
String fromJson;
try {
fromJson = Files.readAllBytes(path).toString();
stocksList = json.fromJson(fromJson, stockType);
return stocksList;
} catch (IOException e) {
return stocksList;
}
}
}
Мой второй подход состоял в том, чтобы вывести список из класса-обертки и попытаться преобразовать его. на JSON:
public class JSONConverter {
private static Path path = Paths.get("src\\json\\JSONList.json");
private static Type listType = new TypeToken<List<Stock>>(){}.getType();
public static void convertToJSON(StocksList stocks, Path path) {
Gson json = new Gson();
List<Stock> temp = stocks.getStocks();
String storedStocks = json.toJson(temp, listType);
checkForFile(path);
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
writer.write(storedStocks);
} catch (IOException e) {
e.printStackTrace();
//handle later
}
}
static void checkForFile(Path path) {
if (Files.notExists(path)) {
try {
Files.createFile(path);
} catch (IOException e) {
e.printStackTrace();
//handle later
}
}
}
public static StocksList convertFromJSON(Path path) {
StocksList stocksList = new StocksList();
List<Stock> stocks = new ArrayList<>();
Gson json = new Gson();
String fromJson;
try {
fromJson = Files.readAllBytes(path).toString();
stocks = json.fromJson(fromJson, listType);
//wraps the list in the stockslist class
stocksList.setStocks(stocks);
return stocksList;
} catch (IOException e) {
e.printStackTrace();
return stocksList;
}
}
}
Вот пример JSON, написанный первым методом с использованием второго подхода. Первый выглядит так, за исключением добавления "{" stocks ":" (что вы видите ниже) "}":
[
{
"ticker": "INTC",
"currentPrice": "45.94",
"marginOfSafety": 0.25,
"lastDate": "2019-12-28",
"cashYield": "7.4",
"MCap": "196485365760",
"enterpriseValue": "281213850000",
"sharesOut": "4417000000",
"oddPercentGrowth": false,
"newCompany": false,
"safeValue": "51.35",
"fairValue": "68.47",
"evEbitda": "8.56",
"fcf": [
"16932000000",
"14611750000"
],
"rOnAssets": "21",
"rOnCapital": "20",
"croic": "16.47",
"equityToDebt": "3.0",
"cashOnHand": "4194000000",
"cashToDebt": "0.17",
"changeInDebt": "210000000",
"capEfficiency": [
"18",
"7",
"-26",
"-21",
"1"
],
"fcfChange": [
"18.81",
"11.71"
],
"profitMargin": [
"46",
"38"
]
},
{
"ticker": "HCC",
"currentPrice": "12.99",
"marginOfSafety": 0.5,
"lastDate": "2018-12-31",
"cashYield": "46.1",
"MCap": "664587904",
"enterpriseValue": "1572623480",
"sharesOut": "52812000",
"oddPercentGrowth": true,
"newCompany": true,
"safeValue": "236.94",
"fairValue": "473.87",
"evEbitda": "2.59",
"fcf": [
"457776000",
"306126750"
],
"rOnAssets": "49",
"rOnCapital": "59",
"croic": "38.77",
"equityToDebt": "1.0",
"cashOnHand": "205577000",
"cashToDebt": "0.44",
"changeInDebt": "125283000",
"capEfficiency": [
"292",
"798",
"-365",
"-397",
"-1"
],
"fcfChange": [
"33.9",
"33.9"
],
"profitMargin": [
"40",
"8"
]
}
]
Оба броска:
com.google.gson .JsonSyntaxException: java .lang.IllegalStateException: ожидалось BEGIN_OBJECT, но было STRING в строке 1 столбца 12
(эта строка изменяется на «Ожидаемый BEGIN_OBJECT, но была BEGIN_ARRAY в строке 1 столбца 2» при использовании первый подход). в
com.google.gson.internal.bind.ReflectiveTypeAdapterFactory $ Adapter.read (ReflectiveTypeAdapterFactory. java: 176) ...
я собирался попробуйте добавить каждый объект по отдельности в JSONArray, но когда у меня возникли проблемы, я решил просто спросить. В руководстве упоминалось, что рефлексия была важна, и я предполагаю, что моя проблема в этом заключается из-за второй строки трассировки стека, но опять же, я впервые пытаюсь использовать JSON. Если я забыл включить что-либо, дайте мне знать, и я опубликую это в комментарии.
Спасибо за помощь.
ADDENDUM: объекты выдают эти исключения только при записи и извлечении из файла. Они не бросают при преобразовании в JSON String, а затем снова обратно. Это происходит независимо от того, использую ли я Files.write () или Files.newBufferedWriter ().