当前位置: 首页 > 知识库问答 >
问题:

格森。toJson()错误排序项目

宋正真
2023-03-14

我有以下输出:

{
  "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;
    }

你可以在这篇文章中找到游戏、玩家头像和游戏玩家类的详细信息:https://stackoverflow.com/a/33048622

有人知道我怎样才能正确订购这个吗?

共有2个答案

阎卓
2023-03-14

根据定义,JSON对象是无序的——您不应该依赖于属性的顺序。所以gson所做的一切都很好。

如果出于某种原因,您别无选择,只能依赖于排序,那么这个问题有一些解决方案:如何在Gson序列化中保持字段顺序(例如,使用jackson而不是Gson,并使用@JsonPropertyOrder,或实现自定义序列化程序)。

在当前的gson和JDK实现中,重新排序类中的成员将以相应的顺序生成输出,然而这是一个非常脆弱的解决方案。例如

>

  • JDK不能保证通过反射读取字段的顺序,将来可能会发生变化(过去已经发生了变化),这会破坏代码。(这实际上是最不可能的问题,但也是可能的)。实际上,JDK 8文档明确表示

    返回数组中的元素没有排序,也没有任何特定的顺序

    如果您编写代码只是为了自己的娱乐,或者使用一次来转换一些数据,这可能没什么大不了的,但如果您正在编写其他人(甚至未来的您)需要维护的代码,我强烈建议您编写不依赖于多层假设和/或持续测试的代码,以确保多个未记录的行为没有改变。

    现在花几分钟合并代码以实际保证字段的顺序可以节省数小时或数天的调试时间。这在现实生活中经常发生。

  • 俞涵涤
    2023-03-14

    Gson根据对象的字段声明顺序创建json字符串(因为它使用Java反射顺序,所以反射字段实际上在jdk 6上的声明顺序中,但在jdk 7之后会更改)

    确保你的JDK是6。Gson是min 2.2.4版本。

    private Long id;
    private String name;
    private List<Player> players;
    

    打印为json字符串:首先是id,然后是球员姓名。

    {
      "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 string: id、玩家和名称。

    {
      "id": 171799578198,
      "players": [
        {
          "avatar": {
            "userId": 21393,
            "currentHomeId": 21393,
            "clanId": 171799578198
          }
        },
        {
          "avatar": {
            "userId": 64425223942,
            "currentHomeId": 64425223942,
            "clanId": 171799578198
          }
        }
      ],
      "name": "Forum Striking"
    }
    

    所以你们应该在游戏对象的末尾声明玩家列表。

     类似资料:
    • 我想从我的对象生成一个JSON字符串: 每次我尝试这样做,我得到这个错误: 这些是我的BomItem类的属性: 我引用的BomModule类的属性: 知道是什么导致了这个错误吗?我该如何修复它?

    • 用户错误报告显示偶尔会返回,但对于大多数用户来说,它工作正常。 我访问了一位用户,他在手机上遇到了错误并调试了应用程序,我制作了来显示发送到服务器的内容,我看到Toast显示了,并且记录和ID不是。 这是我所做的。 这里我做序列化对象 但是)对于一些用户来说是正确的,但是对于一些用户来说返回 服务器数据库显示一些用户发送了数据,但一些用户发送了正确的json。经过一些研究,我发现了新的Gson()

    • 当我将Object转换为Json时,我遇到了大十进制精度丢失的问题。 假设我有Pojo类, 现在我将值设置为Pojo,然后转换为JSON 第一次测试-正确输出 第二次测试-输出错误(失去BigDecimal精度) 第三次测试-输出错误(失去BigDecimal精度) 令人惊讶的是,每当BigDecimal值的长度更大时,它也会截断小数点。json转换有什么问题。你能给我提供解决方案吗?

    • 我正在尝试使用方法,但它正在重新生成类的对象哈希代码,例如: 但是,我可以检索用户。没有任何问题和所有关系的专业知识: 这是我的Gson方法: 这是我的MyTypeAdapter: } 那么,如何让实际返回一个Json字符串,以便我可以使用Gson. FromJson在我的另一端?提前谢谢。

    • 问题内容: 我有一个具有以下结构的User对象: 我有一个具有以下结构的JSON字符串: 属性的键是字符串,属性的值可以是字符串,整数,数组,布尔值,映射等。 我尝试像这样用Gson反序列化此JSON字符串: 字段“ id”和“名称”已正确注入,但字段“属性”保持为空。 你知道我在做什么错吗?在此先感谢您的帮助! 问题答案: 对我来说这段代码: 打印此: 但是,请记住,我在解析的文件中剥离了包装的

    • 我正在尝试使用改装将图像上载到本地服务器。下面是我的php代码。 但是我得到了这样一个错误:com.google.gson.stream.MalformedJsonException使用JsonReader.setLenient(true)在第1行第1列路径$处接受格式错误的JSON。 然后,我在初始化改装的类中添加了以下代码。 现在我得到以下错误:com.google.gson.JsonSynt