Groovy - 如何将 json 转换为精确类型列表

Groovy - How to convert json to a list of exact types

我来自 Java 背景并且是 Groovy-Spock 测试的新手。我需要将 Json 中的列表转换为列表。我无法分享确切的代码(专有),但本质上是这样。

emp_test_data.json

[{
    "empID":"1234",
    "location":"HQ"
  },
  {
    "empID":"5678",
    "location":"Warehouse"
}]

Groovy代码

List<Employee> employeeList = slurper.parse(new File("src/test/resources/data/emp_test_data.json"))

println ("After slurped")  //prints
println(pickupVOList.size()  //prints 2
println(pickupVOList.get(0))  //prints [empID:5678, location:HQ]

empUtil.processEmployees(employeeList)

EmpUtil.java

public void processEmployees(List<Employee> employeeList) {
    for (Employee employee: employeeList) { //THIS FAILS!
        //Do some processing
    }
    return;
}

我得到的错误是:- java.lang.ClassCastException: groovy.json.internal.LazyMap 无法转换为 com.my.domain.Employee

我环顾四周。在 Groovy 中,必须有将 json 转换为精确对象列表的正确方法,而不是 LazyMap 列表,但我似乎找不到它。

有什么想法吗?

Groovy 的 JsonSlurper class 中没有对 POJO 功能的反序列化。但是,您可以将 LazyMap 个条目的列表转换为 Employee 个对象的列表。我不知道你的 Employee class 到底是什么样子,但我们假设它只有这两个字段,并且有一个构造函数接受两个参数 - empIDlocation.

File file = new File("src/test/resources/data/emp_test_data.json")
List<Employee> employeeList = slurper.parse(file).collect {
    new Employee(it.empID, it.location)
}

如果您的 Employee class 遵循 POJO 约定(默认非参数构造函数,setters/getters),那么您可以这样做:

File file = new File("src/test/resources/data/emp_test_data.json")
List<Employee> employeeList = slurper.parse(file).collect {
    def emp = new Employee()
    emp.empID = it.empID
    emp.location = it.location
    return emp
}

或者甚至将转换部分提取到闭包中以提高代码的可读性:

Closure asEmployee = { Map map ->
    def emp = new Employee()
    emp.empID = map.empID
    emp.location = map.location
    return emp
}
File file = new File("src/test/resources/data/emp_test_data.json")
List<Employee> employeeList = slurper.parse(file).collect(asEmployee)

现在您的 Java 代码应该满足正确的静态类型。

怎么样:

List<Employee> employeeList = new JsonSlurper().parse(file).collect(it as Employee)

此代码(基于页面 baeldung.com/groovy-json)给出了 List 的输出:

def jsonSlurper = new JsonSlurper(type: JsonParserType.INDEX_OVERLAY)
def parsedList = jsonSlurper.parseText('[
    {"id":"123","createdAt":"2018-01-01T02:00:00+0000"}, 
    {"id":"124","createdAt":"2018-01-01T02:00:00+0000"}
    ]')
def objectList = parsedList.collect {it as Acc}