我目前遇到了常规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 example code看,似乎应该维护顺序,实际上,看起来toJson方法迭代于object.properties,这是一个LinkedHashMap。我原以为这会按照它们在类中声明的顺序遍历属性。
我最好的猜测是,这与我对游戏对象的初始化有关 - 可以使用Map语法以某种方式分配属性,但同样,这似乎创建了一个应该保留顺序的LinkedHashMap。
有没有人知道我可能做错了什么或错误地假设在这里?任何线索都会有很大的帮助!
答案 0 :(得分:5)
问题是您要将Object序列化为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对象。
另一种选择是编写自己的自定义构建器,这要复杂得多......