1

我目前在使用 groovy JsonBuilder 时遇到问题:我尝试序列化的对象的属性以看似随机的顺序出现。

这是对象的类:

class Game {
    String title
    String gameImg2
    String description
}

这是我一直在使用的代码:

def game = new Game(title: "a game", gameImg2: "an image", description: "desc")
def json = new JsonBuilder(game)

由此我希望输出是:

{"title":"a game","gameImg2":"an image", "description":"desc"}

但相反,我得到:

{"gameImg2":"gameImg","title":"hello","description":"desc"}.

JsonBuilder 示例代码来看,似乎应该保持顺序,实际上,toJson 方法似乎迭代了 object.properties,它是一个 LinkedHashMap。我原以为这会按照它们在类中声明的顺序遍历属性。

我最好的猜测是,这与我对游戏对象的初始化有关 - 可以使用 Map 语法以某种方式分配属性,但同样,这似乎创建了一个应该保持顺序的 LinkedHashMap。

有没有人知道我在这里做错了什么或错误假设?任何线索都会有很大帮助!

4

1 回答 1

6

问题是您正在将对象序列化为 JSON。该对象已声明转换为 Java 的字段。

在 Java 中,不可能(很容易)按照声明的顺序遍历字段,并且 JsonBuilder 代码绝对不会尝试允许这种行为。

查看 JsonBuilder 的源代码可以看到它使用了一个名为 JsonOutput.groovy 的类来序列化您传递给它的 Object,如下所示:

static String toJson(object) {
    if (object == null) {
        "null"
    } else if (object instanceof Collection ||
            object.class.isArray() ||
            object instanceof Iterator ||
            object instanceof Enumeration) {
        "[" + object.collect { toJson(it) }.join(',') + "]"
    } else if (object instanceof Enum) {
        '"' + object.name() + '"'
    } else {
        def properties = object.properties
        properties.remove('class')
        properties.remove('declaringClass')
        properties.remove('metaClass')
        toJson(properties)
    }
}

如您所见,代码调用返回对象成员的对象的属性成员,字段的顺序取决于 JVM 而不是声明的顺序。

如果要保持顺序,则需要传入表示对象的映射或手动按顺序构建 JSON 对象。

另一种选择是编写自己的自定义构建器,这要复杂得多......

于 2012-06-10T22:55:52.047 回答