如何在json文件中使用gson保存数据?

时间:2022-09-19 21:35:07

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表中显示数据。现在我想在一个json文件中保存Mysql表的记录并创建一个用户数组,我用过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();

3 个解决方案

#1


36  

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 转换为json并将其写入一次(无需循环)

Example:

例:

try (Writer writer = new FileWriter("Output.json")) {
    Gson gson = new GsonBuilder().create();
    gson.toJson(users, writer);
}

#2


1  

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 type = new TypeToken<Map<String, Object>>() { }.getType();

#3


0  

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-shmuli,但只有当你省略数据并且只保留数组时才可以在没有适配器的情况下完全生成List。生成的JSON代码如下所示:

[
    {"id":1, "name": "Mike"},
    {"id":2, "name": "Lucy"}
]

Hope it helps to the beginners.

希望它对初学者有所帮助。

#1


36  

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 转换为json并将其写入一次(无需循环)

Example:

例:

try (Writer writer = new FileWriter("Output.json")) {
    Gson gson = new GsonBuilder().create();
    gson.toJson(users, writer);
}

#2


1  

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 type = new TypeToken<Map<String, Object>>() { }.getType();

#3


0  

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-shmuli,但只有当你省略数据并且只保留数组时才可以在没有适配器的情况下完全生成List。生成的JSON代码如下所示:

[
    {"id":1, "name": "Mike"},
    {"id":2, "name": "Lucy"}
]

Hope it helps to the beginners.

希望它对初学者有所帮助。