如何使用GSON解析JSON文件

68

我有一个非常简单的JSON,其中包含产品评论,例如:

{
  "reviewerID": "A2XVJBSRI3SWDI", 
  "asin": "0000031887", 
  "reviewerName": "abigail", 
  "helpful": [0, 0], 
  "unixReviewTime": 1383523200, 
  "reviewText": "Perfect red tutu for the price. ", 
  "overall": 5.0, 
  "reviewTime": "11 4, 2013", "summary": "Nice tutu"
}
{ 
  "reviewerID": "A2G0LNLN79Q6HR", 
  "asin": "0000031887", 
  "reviewerName": "aj_18 \"Aj_18\"", 
  "helpful": [1, 1], 
  "unixReviewTime": 1337990400, 
  "reviewText": "This was a really cute", 
 "overall": 4.0, 
 "reviewTime": "05 26, 2012", 
 "summary": "Really Cute but rather short."
}

我想使用GSON将其读入我的Java应用程序中。我已经构建了一个类来保存每个评论的结果:

public class Review {
    private String reviewerID;
    private String asin;
    private String reviewerName;
    private ArrayList<Integer> helpful;
    private String reviewText;
    private Double overall;
    private String summary;
    private Long unixReviewTime;
    private String reviewTime;

    public Review() {
        this.helpful = Lists.newArrayList();
    }
    // some getters and setters...

为了读取JSON文件,我的代码是:

Gson gson = new Gson();
JsonReader reader = new JsonReader(new FileReader(filename));
Review data = gson.fromJson(reader, Review.class);
data.toScreen(); // prints to screen some values

使用这段代码,我只能检索JSON中的第一个评论,所以我的问题是:如何遍历所有读者并获取下一个评论? 我不需要将评论存储在列表中,只需要访问对象一次。 任何帮助都非常欢迎。


将收到的字符串解析为新的JSONArray()。对于数组中的每个对象,执行gson.fromJson(object, Review.class),然后将它们全部添加到一个空的List<Review> list = new LinkedList<Review>()中。也就是说,按顺序逐个解析它们。 - Schaka
3个回答

115

你需要获取列表中的所有数据,然后进行迭代操作,因为它类似于文件,否则效率会变得低下。

private static final Type REVIEW_TYPE = new TypeToken<List<Review>>() {
}.getType();
Gson gson = new Gson();
JsonReader reader = new JsonReader(new FileReader(filename));
List<Review> data = gson.fromJson(reader, REVIEW_TYPE); // contains the whole reviews list
data.toScreen(); // prints to screen some values

4
我发现您的代码出现了错误:java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $。 - user299791
1
请检查您的JSON文件是否格式正确,可以在jsonlint上进行检查。 - Archit Maheshwari
1
@Archit Maheshwari - 输入格式正确且有效。它包含两个类型为“object”的JSON数据结构。你的例子似乎不起作用,至少在gson 2.8.0中是这样的。尽管如此,我认为你的例子提供了一个有趣的解决问题的方法。我建议将其添加到Gson的愿望清单中。 - wh81752
8
为什么要使用类型(Type),而不只是Review[] data = gson.fromJson(reader, Review[].class); - Line
在这里,您不需要使用TypeToken。只有在处理泛型并且需要添加类型以确保Gson可以解析它时才需要TypeToken。如果您想要更多详细信息,可以访问https://github.com/google/gson/blob/master/UserGuide.md#TOC-Gson-With-Gradle。 - paul_f
@user299791 - 你的JSON输入应该是一个列表,即[{review1 json},{review2 json}],这样就不会出现IllegalStateException。 - kunal

31

只需将其解析为数组:

Review[] reviews = new Gson().fromJson(jsonString, Review[].class);

然后如果您需要,也可以用以下方式创建列表:

List<Review> asList = Arrays.asList(reviews);

附言:您的JSON字符串应该长这个样子:

[
    {
        "reviewerID": "A2SUAM1J3GNN3B1",
        "asin": "0000013714",
        "reviewerName": "J. McDonald",
        "helpful": [2, 3],
        "reviewText": "I bought this for my husband who plays the piano.",
        "overall": 5.0,
        "summary": "Heavenly Highway Hymns",
        "unixReviewTime": 1252800000,
        "reviewTime": "09 13, 2009"
    },
    {
        "reviewerID": "A2SUAM1J3GNN3B2",
        "asin": "0000013714",
        "reviewerName": "J. McDonald",
        "helpful": [2, 3],
        "reviewText": "I bought this for my husband who plays the piano.",
        "overall": 5.0,
        "summary": "Heavenly Highway Hymns",
        "unixReviewTime": 1252800000,
        "reviewTime": "09 13, 2009"
    },

    [...]
]

您的代码出现了错误:com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: 期望在 $ 路径下的第一行第一列得到一个值。 - user299791
抱歉,我的文件有3GB,我尝试使用VIM加载它,但无法加载。 - user299791
只显示文件的前几个字节。我猜你的 JSON 字符串不合法。 - dieter
兄弟,如果你告诉我怎么做,我会非常感激!!!我用的是Mac OSX... 你有一行命令可以在终端中复制显示吗? - user299791
你是程序员,用Java做吧 :) :http://www.mkyong.com/java/how-to-read-file-from-java-bufferedreader-example/ 只需要第一行。 - dieter
让我们在聊天中继续这个讨论 - user299791

7

如果您需要从文件中解析它,我发现最好的解决方案是使用 HashMap<String, String> 在Java代码中使用它以便更好地操作。

尝试使用以下代码:

public HashMap<String, String> myMethodName() throws FileNotFoundException
{
    String path = "absolute path to your file";
    BufferedReader bufferedReader = new BufferedReader(new FileReader(path));

    Gson gson = new Gson();
    HashMap<String, String> json = gson.fromJson(bufferedReader, HashMap.class);
    return json;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接