Java 如何使用gson将数据保存在json文件中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29319434/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to save data with gson in a json file?
提问by mak_doni
In my web application I succeed in displaying data in html table using mybatis. Now I want to save the records of the Mysql table in a json file and create an array of users, I used Gson, the problem is that just one record saved in the file. Thanks.
Here the result in file.json
:
在我的 Web 应用程序中,我成功地使用 mybatis 在 html 表中显示数据。现在我想将Mysql表的记录保存在一个json文件中并创建一个用户数组,我使用了Gson,问题是文件中只保存了一个记录。谢谢。
这里的结果是file.json
:
{"data":
[
{"id":2,"Name":"Mike"}
]
}
servlet.java
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();
采纳答案by Roy Shmuli
You write all the users in same file C:\\file.json
so just the last iteration of the loop saved.
您将所有用户写入同一个文件中,C:\\file.json
因此只保存了循环的最后一次迭代。
You can convert the object List<User>
into json and write it once (no needed loop)
您可以将对象List<User>
转换为 json 并编写一次(无需循环)
Example:
例子:
try (Writer writer = new FileWriter("Output.json")) {
Gson gson = new GsonBuilder().create();
gson.toJson(users, writer);
}
回答by sonavolob
I was previously using outputStream.writeObject and Serializable with default writer/reader for saving object data. Because of problems with code sustainability I have been after something else. This is the result. That BufferedWriter is mandatory, otherwise write speed drops 8 times. Notice that UTF-8 declaration which is default encoding of Json. Not sure whether not declaring it is safe.
我以前使用 outputStream.writeObject 和 Serializable 与默认写入器/读取器来保存对象数据。由于代码可持续性问题,我一直在追求其他东西。这是结果。该 BufferedWriter 是强制性的,否则写入速度下降 8 倍。请注意 UTF-8 声明,它是Json 的默认编码。不确定是否不声明它是安全的。
Example:
例子:
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;
}
where Type for example:
输入例如:
Type type = new TypeToken<Map<String, Object>>() { }.getType();
回答by nessa.gp
Quick fix to your code:
快速修复您的代码:
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();
}
However, in the case that your User class looks like this:
但是,如果您的 User 类如下所示:
public class User {
String id;
String name;
}
Then you don't need to code the adapter as Gson is able to automatically generate the JSON code for a class that only has primitives (ints, Strings, etc.). So your code would look as @roy-shmuli but only if you omit the data and keep only the array as List can be completely generated without an adapter. The JSON code generated would look like this:
然后,您无需编写适配器代码,因为 Gson 能够为只有基元(整数、字符串等)的类自动生成 JSON 代码。所以你的代码看起来像@roy-shmili,但前提是你省略了数据并只保留了数组,因为 List 可以在没有适配器的情况下完全生成。生成的 JSON 代码如下所示:
[
{"id":1, "name": "Mike"},
{"id":2, "name": "Lucy"}
]
Hope it helps to the beginners.
希望对初学者有所帮助。