我有这个输出JSON。
{
"id": 42950262095,
"name": "lol",
"players": [
{
"avatar": {
"userId": 25771876384,
"userName": "yhht",
"role": "Leader",
"level": 40,
"league": 0,
"trophies": 1011,
"donatedTroops": 0,
"receivedTroops": 0
}
},
{
"avatar": {
"userId": 146035414262,
"userName": "ari",
"role": "New Member",
"level": 8,
"league": 0,
"trophies": 428,
"donatedTroops": 0,
"receivedTroops": 0
}
},
{
"avatar": {
"userId": 300659467521,
"userName": "cp 221",
"role": "New Member",
"level": 6,
"league": 0,
"trophies": 97,
"donatedTroops": 0,
"receivedTroops": 0
}
}
],
"badge": 13000049,
"status": "Anyone Can Join",
"playerCount": 3,
"score": 767,
"requiredTrophies": 0,
"warsWon": 0,
"warsLost": 0,
"warsTied": 0,
"warFrequency": 0,
"exp": 0,
"level": 1,
"description": "??lol????"
}
但问题是球员数组来得太早,部分初始细节被遗漏了。
这是我的代码。
public void parseAvatar() throws IOException, JSONException{
Game game = new Game();
game.setId(is.readLong());
game.setName(is.readString());
game.setBadge(is.readInt());
game.setStatus(status(is.readInt()));
game.setPlayerCount(is.readInt());
game.setScore(is.readInt());
game.setRequiredTrophies(is.readInt());
game.setWarsWon(is.readInt());
game.setWarsLost(is.readInt());
game.setWarsTied(is.readInt());
is.readInt();
game.setWarFrequency(is.readInt());
is.readInt();
game.setExp(is.readInt());
game.setLevel(is.readInt());
game.setDescription(is.readString());
is.readInt();
boolean a = is.readBoolean();
if(a){
is.readInt();
is.readInt();
}
int memCount = is.readInt();
/// Members!!
int i = 0;
while(i < memCount){
PlayerAvatar avatar = new PlayerAvatar();
avatar.setUserId(is.readLong());
avatar.setUserName(is.readString());
avatar.setRole(role(is.readInt()));
avatar.setLevel(is.readInt());
avatar.setLeague(is.readInt());
avatar.setTrophies(is.readInt());
avatar.setDonatedTroops(is.readInt());
avatar.setReceivedTroops(is.readInt());
is.readInt();
is.readInt();
is.readLong();
is.readByte();
is.readByte();
is.readLong();
GamePlayer player = new GamePlayer();
player.setAvatar(avatar);
game.addPlayers(player);
i++;
}
json = new Gson().toJson(game);
System.out.println();
}
private String role(int role) {
String memberRole = "";
if(role == 1){
memberRole = "New Member";
}
if(role == 2){
memberRole = "Leader";
}
if(role == 3){
memberRole = "Elder";
}
if(role == 4){
memberRole = "Co Leader";
}
return memberRole;
}
private String status(int statusint) {
String type = null;
if(statusint == 1){
type = "Anyone Can Join";
}
if(statusint == 2){
type = "Invite Only";
}
if(statusint == 3){
type = "Closed";
}
return type;
}
你可以在这篇文章中找到Game, PlayerAvatar和GamePlayer类的细节: https: /stackoverflow.coma33048622
有谁知道如何才能让这个正确排序?
Gson根据你的对象的字段声明顺序创建json字符串(因为它使用的是 "json字符串"。Java reflection ordering
在jdk 6上,反映出的字段的声明顺序是一致的,但在jdk 7之后就改变了。)
确保你的JDK是6.Gson是最小2.2.4版本。
private Long id;
private String name;
private List<Player> players;
打印为json字符串:首先是id,name,然后是player。
{
"id": 171799578198,
"name": "Forum Striking",
"players": [
{
"avatar": {
"userId": 21393,
"currentHomeId": 21393,
"clanId": 171799578198
}
},
{
"avatar": {
"userId": 64425223942,
"currentHomeId": 64425223942,
"clanId": 171799578198
}
}
]
}
private Long id;
private List<Player> players;
private String name;
打印为json字符串:最后是id,player和name。
{
"id": 171799578198,
"players": [
{
"avatar": {
"userId": 21393,
"currentHomeId": 21393,
"clanId": 171799578198
}
},
{
"avatar": {
"userId": 64425223942,
"currentHomeId": 64425223942,
"clanId": 171799578198
}
}
],
"name": "Forum Striking"
}
所以你应该在游戏对象的最后声明玩家列表。
JSON对象的定义是无序的--你不应该依赖属性的顺序。所以gson的做法是完全正确的。
如果出于某些原因,你别无选择,只能依靠排序,在这个问题上有一些解决方案。如何在Gson序列化中保持字段顺序 (例如,用jackson代替gson,用 @JsonPropertyOrder
或实现一个自定义的序列器)。)
有了 当前 gson和JDK的实现,重新排序你的类中的成员将产生相应顺序的输出,然而这是一个非常脆弱的解决方案。例如
返回数组中的元素没有排序,也没有任何特定的顺序。
HashMap
,顺序就会改变,你的代码就会崩溃。如果你写的代码只是为了自娱自乐,或者是为了用一次转换一些数据,那可能没什么大不了的,但如果你写的代码是别人(甚至是 未来的你)将需要维护,我 强烈 建议你写的代码不要依赖于层层假设,也不要依赖于不断的测试来确保多种未记录的行为没有改变。
现在花几分钟时间加入代码来实际保证你的字段的排序,可以节省几个小时或几天的调试时间。这种情况会发生 无时无刻 在现实生活中。