用Gson反序列化JSON - 预期BEGIN_OBJECT但是字符串 - Reddit的JSON

时间:2014-02-03 22:35:50

标签: serialization gson reddit

我正在尝试从Reddit反序列化JSON,你可以通过将.json附加到url来获得。一个例子是:

http://www.reddit.com/r/pics/comments/1wvx52/.json?sort=top

但是,我收到错误消息:

线程“main”中的异常com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期为BEGIN_OBJECT但在第1行第9765行为STRING

在json的第1行第9765行,有以下代码:“replies”:“”,而通常这将包含如下对象:回复:{ 善良:“上市”, 数据:{} },

这是否意味着json在没有数据时是一个String,而在另一个对象中是什么?如果是这种情况,如何正确地使用gson反序列化?我在下面列出了我的课程。我仍然需要弄清楚如何处理json从一个基本上两个不同对象的数组开始(json中的第一个列表描述了链接,而第二个列表描述了注释),但我将穿过那个桥当我到达时。如果有人能够对这个问题有所了解,请提前致谢。

主类

public static void main(String[] args)
{
    ArrayList<CommentsResults> commentsResults = new ArrayList<CommentsResults>();
    String commentsURL = "http://www.reddit.com/r/pics/comments/1wvx52/.json?sort=top";
    URL url = null;
    try
    {
        url = new URL(commentsURL);
    } catch (MalformedURLException ex)
    {
        System.out.println(ex.getMessage());
    }

    try
    {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
        String jsonText = readAll(bufferedReader);
        Gson gson = new GsonBuilder().create();
        commentsResults = gson.fromJson(jsonText, new TypeToken<ArrayList<CommentsResults>>(){}.getType());
    } catch (IOException ex)
    {
        System.out.println(ex.getMessage());
    }
}
private static String readAll(Reader reader) throws IOException
{
    StringBuilder stringBuilder = new StringBuilder();
    int cp;
    while ((cp = reader.read()) != -1)
    {
        stringBuilder.append((char) cp);
    }
    return stringBuilder.toString();
}

CommentsResults Class

public class CommentsResults {

private String kind;
private CommentsData data;    

public CommentsResults()
{
}

public CommentsResults(String kind, CommentsData data)
{
    this.kind = kind;
    this.data = data;
}

public String getKind()
{
    return kind;
}

public CommentsData getData()
{
    return data;
}

public void setKind(String kind)
{
    this.kind = kind;
}

public void setData(CommentsData data)
{
    this.data = data;
}    

}

CommentsData Class

private String modhash;
private List <CommentsChild> children; 

public CommentsData()
{
}

public CommentsData(String modhash, List<CommentsChild> children)
{
    this.modhash = modhash;
    this.children = children;
}

public String getModhash()
{
    return modhash;
}

public List<CommentsChild> getChildren()
{
    return children;
}

public void setModhash(String modhash)
{
    this.modhash = modhash;
}

public void setChildren(List<CommentsChild> children)
{
    this.children = children;
}       

CommentsChild Class

private String kind;
private Comment data;

public CommentsChild()
{
}

public CommentsChild(String kind, Comment comment)
{
    this.kind = kind;
    this.data = comment;
}

public String getKind()
{
    return kind;
}

public Comment getComment()
{
    return data;
}

public void setKind(String kind)
{
    this.kind = kind;
}

public void setComment(Comment comment)
{
    this.data = comment;
} 

评论类

public class Comment {

private CommentsResults replies;

private String id;

private int gilded;

private String author;

private String parent_id;

private String body;

private int downs;

private String link_id;

private boolean score_hidden;

private int created_utc;

private String distinguished;

public Comment()
{
}

public Comment(CommentsResults replies, String id, int gilded, String author, String parent_id, String body, int downs, String link_id, boolean score_hidden, int created_utc, String distinguished)
{
    this.replies = replies;
    this.id = id;
    this.gilded = gilded;
    this.author = author;
    this.parent_id = parent_id;
    this.body = body;
    this.downs = downs;
    this.link_id = link_id;
    this.score_hidden = score_hidden;
    this.created_utc = created_utc;
    this.distinguished = distinguished;
}

public CommentsResults getReplies()
{
    return replies;
}

public String getId()
{
    return id;
}

public int getGilded()
{
    return gilded;
}

public String getAuthor()
{
    return author;
}

public String getParent_id()
{
    return parent_id;
}

public String getBody()
{
    return body;
}

public int getDowns()
{
    return downs;
}

public String getLink_id()
{
    return link_id;
}

public boolean isScore_hidden()
{
    return score_hidden;
}

public int getCreated_utc()
{
    return created_utc;
}

public String getDistinguished()
{
    return distinguished;
}

public void setReplies(CommentsResults replies)
{
    this.replies = replies;
}

public void setId(String id)
{
    this.id = id;
}

public void setGilded(int gilded)
{
    this.gilded = gilded;
}

public void setAuthor(String author)
{
    this.author = author;
}

public void setParent_id(String parent_id)
{
    this.parent_id = parent_id;
}

public void setBody(String body)
{
    this.body = body;
}

public void setDowns(int downs)
{
    this.downs = downs;
}

public void setLink_id(String link_id)
{
    this.link_id = link_id;
}

public void setScore_hidden(boolean score_hidden)
{
    this.score_hidden = score_hidden;
}

public void setCreated_utc(int created_utc)
{
    this.created_utc = created_utc;
}

public void setDistinguished(String distinguished)
{
    this.distinguished = distinguished;
}    
}

2 个答案:

答案 0 :(得分:1)

所以在关闭机会这有助于某人(此时看起来很可疑)我决定使用递归手动解析Json。我是这样做的:

public static void getCommentsOnLink()
{               
    String commentsURL= "http://www.reddit.com/r/pics/comments/1wvx52/.json?sort=top";
    URL url = null;
    try
    {
        url = new URL(commentsURL);
    } catch (MalformedURLException ex)
    {
        System.out.println(ex.getMessage());
    }
    String JsonText = readCommentJsonFromURL(url);

    RedditCommentResults redditCommentResults = getCommentResults(JsonText);
}

private static String readCommentJsonFromURL(URL url)
{
    String JSONText = null;
    try
    {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
        JSONText = readAll(bufferedReader);
    } catch (IOException ex)
    {
        System.out.println(ex.getMessage());
    }
    return JSONText;
}

private static String readAll(Reader reader) throws IOException
{
    StringBuilder stringBuilder = new StringBuilder();
    int cp;
    while ((cp = reader.read()) != -1)
    {
        stringBuilder.append((char) cp);
    }
    return stringBuilder.toString();
}    

private static RedditCommentResults getCommentResults(String JsonText)
{
    JsonParser parser = new JsonParser();
    JsonArray completeJson = (JsonArray) parser.parse(JsonText);

    //get link and comment object from the array containing an object for each
    JsonObject linkParentJson = (JsonObject) completeJson.get(0);
    JsonObject commentParentJson = (JsonObject) completeJson.get(1);

    //use automatic deserializer for redditLink
    JsonObject linkListingDataJson = linkParentJson.getAsJsonObject("data");
    JsonObject linkChildrenJson = linkListingDataJson.getAsJsonArray("children").get(0).getAsJsonObject();
    JsonObject linkDataJson = linkChildrenJson.getAsJsonObject("data");
    Link commentLink = gson.fromJson(linkDataJson, Link.class);
    RedditLink redditCommentLink = new RedditLink(commentLink);

    //parse comments manually
    JsonObject commentDataJson = commentParentJson.getAsJsonObject("data");
    JsonArray commentChildrenJson = commentDataJson.getAsJsonArray("children");

    //get all of the comments from the JsonArray
    ArrayList<RedditComment> redditComments = getNestedComments(commentChildrenJson);

    RedditCommentResults redditCommentResults = new RedditCommentResults(redditComments, redditCommentLink);
    return redditCommentResults;
}

private static ArrayList<RedditComment> getNestedComments(JsonArray commentWrapperJsonArray)
{
    ArrayList<RedditComment> redditComments = new ArrayList();
    for (JsonElement commentWrapperJson : commentWrapperJsonArray)
    {
        //cast Element to Object so we can search for the primitive "kind".  Finally we get it as a String
        String kind = commentWrapperJson.getAsJsonObject().getAsJsonPrimitive("kind").getAsString();

        //if the comment is of type t1 meaning it is a comment and not a "more" (a "more" is a comment which 
        //hasn't been loaded yet because it does not have a great deal of upvotes relative to other comments)
        if (kind.equals("t1"))
        {
            JsonObject commentJson = commentWrapperJson.getAsJsonObject().getAsJsonObject("data");
            Comment comment = gson.fromJson(commentJson, Comment.class);
            RedditComment redditComment = new RedditComment(comment);

            JsonElement repliesJson = commentJson.get("replies");

            //if the reply is not equal to an empty String (i.e. if there is at least one reply)
            if (!repliesJson.isJsonPrimitive())
            {
                JsonObject dataJson = repliesJson.getAsJsonObject().getAsJsonObject("data");
                JsonArray childrenJson = dataJson.getAsJsonArray("children");
                ArrayList<RedditComment> nestedComments = getNestedComments(childrenJson);
                redditComment.setReplies(nestedComments);
            }
            redditComments.add(redditComment);
        }
    }
    return redditComments;
}

答案 1 :(得分:0)

您必须从评论类中删除private CommentsResults replies;并撰写 CommentsChild 类中的回复。根据Json fomate你的模型是

CommentResult -
      CommentsData --
            List <CommentsChild> children---
                   CommentsResults replies
                        recursion/ repeation of comment result

public class CommentsChild {
    private String kind;
    private Comment data;
    // 
    private CommentsResults replies;
}