在Groovy中使用Slrowping JSON集合

时间:2014-11-13 13:20:35

标签: json groovy deserialization

我有一个JSON字符串,如下所示:

String json = """
    {       
        "content":{
            "response":{
                "body": [
                    {
                        "firstName":"Jim",
                        "lastName":"Smith"
                    },
                    {
                        "firstName":"Joe",
                        "lastName":"Smith"
                    },
                    {
                        "firstName":"Jane",
                        "lastName":"Smith"
                    }
                ]
            }
        }
    }
"""

我有一个看起来像这样的POJO:

class Person {
    String firstName
    String surname
}

我既不能更改我给出的JSON字符串(它实际上是从Web服务返回的JSON),也不能更改POJO(由其他团队拥有/维护)。

我想将此JSON转换为List<Person>

我在JsonSlurper的尝试失败了:

JsonSlurper slurper = new JsonSlurper()
List<Person> people = []
// The problem is I don't know how many people there will be so
// not sure how to index the slurper.

认为最好的方法是遍历slurper并将每个人JSON对象转换为Person实例,然后将该人添加到people列表中{1}}。但我对JsonSlurper的API并不熟悉,或者最好的方法是什么。

2 个答案:

答案 0 :(得分:3)

您可以通过collect()条目获取列表:

List<Person> l = slurper.content.response.body.collect{ new Person(firstName: it.firstName, surname: it.lastName) }

e.g:

import groovy.json.JsonSlurper
import groovy.transform.ToString

String json = """
    {       
        "content":{
            "response":{
                "body": [
                    {
                        "firstName":"Jim",
                        "lastName":"Smith",
                    },
                    {
                        "firstName":"Joe",
                        "lastName":"Smith",
                    },
                    {
                        "firstName":"Jane",
                        "lastName":"Smith",
                    }
                ]
            }
        }
    }
"""

@ToString
class Person {
    String firstName
    String surname
}

def slurped = new JsonSlurper().parseText(json)
List<Person> l = slurped.content.response.body.collect {new Person(firstName: it.firstName, surname: it.lastName) }
assert l.size() == 3 

答案 1 :(得分:0)

好吧,不需要显式构造Person对象:

(常规 - 壳)

@ToString
class Person {
    String firstName
    String lastName
}

slurped = new JsonSlurper().parseText(json)
l = slurped.content.response.body.collect {it as Person}

只需要确保Person类型完全代表json(例如字段名称相等) 这是一个棘手的部分,因为Groovy解析器有点胡思乱想。我的意思是,如果您不将surname重命名为lastName,则会解析json列表,但所有三个Person实例的所有字段都将保留null

如果你不喜欢动态类型的地图,那么对象就会更加神奇:

@ToString
class Some {
    Content content
}

@ToString
class Content {
    Response response
}

@ToString
class Response {
    Person[] body
}

cnt = slurped as Some
println cnt.dump()

将打印

<Some@62ddbd7e content=Content(Response([Person(Jim, Smith), Person(Joe, Smith), Person(Jane, Smith)]))>