Как сохранить данные с помощью gson в json файле?
В моем веб-приложении мне удается отображать данные в таблице html с помощью mybatis. Теперь я хочу сохранить записи таблицы Mysql в json файле и создать массив пользователей, я использовал Gson, проблема в том, что только одна запись была сохранена в файле. Благодарю.
Вот результат в file.json
:
{"data":
[
{"id":2,"Name":"Mike"}
]
}
servlet.java
SqlSession session = MyBatisSqlSessionFactory.getSession();
List<User> users = session.selectList("dao.UserDao.findAll");
for (User u : users) {
Gson gson = new Gson();
try {
JsonWriter writer = new JsonWriter(new FileWriter("C:\\file.json"));
writer.beginObject();
writer.name("data");
writer.beginArray();
writer.beginObject();
writer.name("id").value(t.getId());
writer.name("name").value(t.getNom());
writer.endObject();
writer.endArray();
writer.endObject();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
session.close();
Ответы
Ответ 1
Вы пишете всех пользователей в том же файле C:\\file.json
чтобы только последняя итерация цикла была сохранена.
Вы можете преобразовать объект List<User>
в json и записать его один раз (нужный цикл)
Пример:
try (Writer writer = new FileWriter("Output.json")) {
Gson gson = new GsonBuilder().create();
gson.toJson(users, writer);
}
Ответ 2
Ранее я использовал outputStream.writeObject и Serializable с помощью записи/чтения по умолчанию для сохранения данных объекта. Из-за проблем с устойчивостью кода я был после чего-то другого. Это результат. Этот BufferedWriter является обязательным, иначе скорость записи снижается 8 раз. Обратите внимание, что декларация UTF-8, которая по умолчанию кодирует Json. Не уверен, что это не безопасно.
Пример:
private void saveJson(Object object, Type type, String directory, String fileName) {
File file = new File(getApplicationContext().getDir(directory, Context.MODE_PRIVATE),
fileName);
OutputStream outputStream = null;
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting()
.create();
try {
outputStream = new FileOutputStream(file);
BufferedWriter bufferedWriter;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,
StandardCharsets.UTF_8));
} else {
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
}
gson.toJson(object, type, bufferedWriter);
bufferedWriter.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
if (DEBUG) Log.e(saveJson, "saveUserData, FileNotFoundException e: '" + e + "'");
} catch (IOException e) {
e.printStackTrace();
if (DEBUG) Log.e(saveJson, "saveUserData, IOException e: '" + e + "'");
} finally {
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
if (DEBUG) Log.e(saveJson, "saveUserData, finally, e: '" + e + "'");
}
}
}
}
private Object loadJson(Type type, String directory, String fileName) {
Object jsonData = null;
File file = new File(getApplicationContext().getDir(directory, Context.MODE_PRIVATE),
fileName);
InputStream inputStream = null;
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting()
.create();
try {
inputStream = new FileInputStream(file);
InputStreamReader streamReader;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
streamReader = new InputStreamReader(inputStream,
StandardCharsets.UTF_8);
} else {
streamReader = new InputStreamReader(inputStream, "UTF-8");
}
jsonData = gson.fromJson(streamReader, type);
streamReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
if (DEBUG) Log.e(TAG, "loadJson, FileNotFoundException e: '" + e + "'");
} catch (IOException e) {
e.printStackTrace();
if (DEBUG) Log.e(TAG, "loadJson, IOException e: '" + e + "'");
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
if (DEBUG) Log.e(TAG, "loadJson, finally, e: '" + e + "'");
}
}
}
return jsonData;
}
где Тип, например:
Type type = new TypeToken<Map<String, Object>>() { }.getType();
Ответ 3
Быстрое исправление кода:
SqlSession session = MyBatisSqlSessionFactory.getSession();
List<User> users = session.selectList("dao.UserDao.findAll");
try {
JsonWriter writer = new JsonWriter(new FileWriter("C:\\file.json"));
writer.beginObject();
writer.name("data");
writer.beginArray();
for (User u : users) {
writer.beginObject();
writer.name("id").value(t.getId());
writer.name("name").value(t.getNom());
writer.endObject();
}
writer.endArray();
writer.endObject();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
Однако в том случае, если ваш класс User выглядит следующим образом:
public class User {
String id;
String name;
}
Тогда вам не нужно закодировать адаптер, так как Gson может автоматически генерировать код JSON для класса, в котором есть только примитивы (ints, Strings и т.д.). Таким образом, ваш код будет выглядеть как @roy-shmuli, но только если вы опустите данные и сохраните только массив, поскольку List может быть полностью сгенерирован без адаптера. Созданный код JSON будет выглядеть так:
[
{"id":1, "name": "Mike"},
{"id":2, "name": "Lucy"}
]
Надеюсь, это поможет новичкам.