将InputStream转换为JsonObject - GSON

36

我在尝试将这个API的结果转换为JsonObject时遇到了很多麻烦。

无论我尝试什么,"result"都保持为空值。

  URL url = new URL(urlString);
  InputStream input = url.openStream();
  Reader reader = new InputStreamReader(in, "UTF-8");
  JsonResult result  = new Gson().fromJson(reader, JsonResult.class);

JsonResult类

public class JsonResult {
    private String status;
    private Meta meta;
    private ArrayList<Player> players;
}

class Meta{
    private String count;
}

JSON:

{"status":"ok","meta":{"count":12},"data":[{"nickname":"DataBase","account_id":500566109},{"nickname":"database007","account_id":514382449},{"nickname":"Database04","account_id":504367425},{"nickname":"database08","account_id":515081772},{"nickname":"database1","account_id":503282284},{"nickname":"database1221","account_id":506709044},{"nickname":"database123","account_id":508409172},{"nickname":"database1337","account_id":501661259},{"nickname":"database169","account_id":503884400},{"nickname":"database2","account_id":504337382},{"nickname":"database93","account_id":518691821},{"nickname":"databaseking66","account_id":505911069}]}

注意:这是一个学校项目。

注2:我确实检查和测试了很多来自SO的其他解决方案,但没有找到或理解正确的解决方案。

编辑1:

public class JsonResult {
    @SerializedName("status")
    public String status;
    @SerializedName("meta")
    public Meta meta;
    @SerializedName("data")
    public Player[] players;
}

class Meta{
    @SerializedName("count")
    private String count;
}

玩家类

public class Player {

    private int account_id;
    private String nickname;

    public Player(int account_id, String nickname){
        this.account_id = account_id;
        this.nickname = nickname;
    }


    //Generated
    public void setAccount_id(int account_id) {
        this.account_id = account_id;
    }

    //Generated
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String toString() {
        return this.account_id + this.nickname;
    }
}

2
你说你遇到了“很多麻烦” - 那么发生了什么?代码是否编译通过?有异常吗?JSON看起来是什么样子的? - Jon Skeet
2
@Jochem,第三方链接不受欢迎,因为它们具有动态性(未来某些人可能会单击链接,但找不到任何有用的信息)。您的帖子必须进行编辑,以包括所有相关内容。_此外,我们中的一些人受到工作场所防火墙的限制;) _ - CubeJockey
@Trobbins 谢谢,马上就会有了 :). 我已经编辑了问题。 - JochemQuery
你的玩家显然被称为“data”。请更改名称或添加注释以指示给Gson。 - njzk2
@njzk2,编辑看起来正确吗?这对我来说都是新的,目前正在测试和调试所有内容。 - JochemQuery
@JochemQuery:没错,看起来不错(@SerializedName 不是所有字段都必须的,但它也可以保护你免受 Proguard 混淆和缩小的影响)。 - njzk2
1个回答

9
在您的JsonResult类中更改:
public class JsonResult {
    private String status;
    private Meta meta;
    @SerializedName("data")
    private ArrayList<Player> players;
}

13
重要的是描述“为什么”这是解决方案。原因是Gson尝试按名称映射属性,而JSON中玩家数组的属性名为“data”,而JsonResult类中没有名称为“data”的属性,因此它无法找到放置它的位置并将其省略。这个注释告诉解析器,在看到“data”属性时使用“players”字段。 - Dave Lugg
感谢@DaveLugg的解释和-Ads的回答。仍然有一些东西导致我出现了空指针错误。我正在重新阅读我的代码并尝试再次运行。 - JochemQuery
@广告完成,我是否缺少“正确”的getter和setter? - JochemQuery
我认为使用与原始JSON属性名称不同的POJO属性名称并不是一个好主意,只有当您无法控制JSON源时,@ SerializedName注释才是必要的,具有与JSON属性相同属性名称的POJO具有更好的可读性。另外,使用List接口而不是实现类更好。 - vzamanillo
2
@vzamanillo 在那里使用注释意味着他可以随时访问他的球员列表,而且人们不会对它的含义感到困惑。如果他为自己的字段使用“数据”,那么他以后可能会在代码中迭代它,而查看代码的人将不知道“数据”代表什么。按照变量所包含的内容命名变量是一个应该遵循的好习惯。JochemQuery 当然由你决定,但我建议保留它。每次在代码中稍后访问球员数组时,更容易理解它所指的内容。 - Dave Lugg
显示剩余4条评论

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