首页 > 解决方案 > Groovy - 如何将 json 转换为精确类型的列表

问题描述

我来自 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 列表,但我似乎找不到它。

有任何想法吗?

标签: groovyspock

解决方案


JsonSlurperGroovy 的类中没有对 POJO 功能的反序列化。但是,您可以将LazyMap条目列表转换为Employee对象列表。我不知道你的Employee类到底长什么样,但我们假设它只有这两个字段,并且有一个接受两个参数的构造函数 -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类遵循 POJO 约定(默认的非参数构造函数,setter/getter),那么您可能会执行以下操作:

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 代码应该对正确的静态类型感到满意。


推荐阅读