从 JsonSlurper 向对象添加强类型
Add strong typing to objects from JsonSlurper
我在使用 Groovy 中的 JsonSlurper
打字时遇到了一些问题。我对 Groovy 还很陌生,对向它添加强类型更陌生 - 请耐心等待。
现在我已经创建了一个 trait
,它定义了我的 JSON 对象的一般形状,我正在尝试将 parseText
的结果投射到它。
import groovy.json.JsonSlurper
trait Person {
String firstname
String lastname
}
def person = (Person)(new JsonSlurper().parseText('{"firstname": "Lando", "lastname": "Calrissian"}'))
println person.lastname
这抛出
Exception in thread "main" org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '{firstname=Lando, lastname=Calrissian}' with class 'org.apache.groovy.json.internal.LazyMap' to class 'Person' due to: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: Person(org.apache.groovy.json.internal.LazyMap)
...
我明白为什么我的代码没有意义,我不是要更改数据类型(转换),我只是想让我的 IDE 知道这是我的对象里面有什么。
是否可以至少向我的 JSON 对象添加代码完成? 我也很想进行运行时类型检查,但这不是必需的.
这实际上是一个演员,Groovy会尝试将您的地图变成所述对象。
来自docs:
The coercion operator (as) is a variant of casting. Coercion converts object from one type to another without them being compatible for assignment.
POJO 的工作方式是使用 Map-c'tor 构造一个新对象。这将展开调用 setter 或直接使用静态编译。
请注意,使用带有过多键的地图会导致错误。所以我只会将其用于玩具项目。使用适当的 JSON-mapper ,例如取而代之的是杰克逊。
所以这里的解决方案是不使用特征(基本上是一个接口),而是使用常规 class.
你可以尝试使用委托
这允许将 class 环绕在地图
周围
import groovy.json.JsonSlurper
class Person {
@Delegate Map delegate
String getFirstname(){ delegate.get('firstname') }
String getLastname(){ delegate.get('lastname') }
}
def person = new Person(delegate:new JsonSlurper().parseText('{"firstname": "Lando", "lastname": "Calrissian"}'))
println person.lastname
或者例如使用 Gson 进行解析:
@Grab(group='com.google.code.gson', module='gson', version='2.8.5')
import com.google.gson.Gson
class Person {
String firstname
String lastname
}
def person = new Gson().fromJson('{"firstname": "Lando", "lastname": "Calrissian"}', Person.class)
assert person instanceof Person
println person.lastname
我在使用 Groovy 中的 JsonSlurper
打字时遇到了一些问题。我对 Groovy 还很陌生,对向它添加强类型更陌生 - 请耐心等待。
现在我已经创建了一个 trait
,它定义了我的 JSON 对象的一般形状,我正在尝试将 parseText
的结果投射到它。
import groovy.json.JsonSlurper
trait Person {
String firstname
String lastname
}
def person = (Person)(new JsonSlurper().parseText('{"firstname": "Lando", "lastname": "Calrissian"}'))
println person.lastname
这抛出
Exception in thread "main" org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '{firstname=Lando, lastname=Calrissian}' with class 'org.apache.groovy.json.internal.LazyMap' to class 'Person' due to: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: Person(org.apache.groovy.json.internal.LazyMap)
...
我明白为什么我的代码没有意义,我不是要更改数据类型(转换),我只是想让我的 IDE 知道这是我的对象里面有什么。
是否可以至少向我的 JSON 对象添加代码完成? 我也很想进行运行时类型检查,但这不是必需的.
这实际上是一个演员,Groovy会尝试将您的地图变成所述对象。
来自docs:
The coercion operator (as) is a variant of casting. Coercion converts object from one type to another without them being compatible for assignment.
POJO 的工作方式是使用 Map-c'tor 构造一个新对象。这将展开调用 setter 或直接使用静态编译。
请注意,使用带有过多键的地图会导致错误。所以我只会将其用于玩具项目。使用适当的 JSON-mapper ,例如取而代之的是杰克逊。
所以这里的解决方案是不使用特征(基本上是一个接口),而是使用常规 class.
你可以尝试使用委托
这允许将 class 环绕在地图
周围import groovy.json.JsonSlurper
class Person {
@Delegate Map delegate
String getFirstname(){ delegate.get('firstname') }
String getLastname(){ delegate.get('lastname') }
}
def person = new Person(delegate:new JsonSlurper().parseText('{"firstname": "Lando", "lastname": "Calrissian"}'))
println person.lastname
或者例如使用 Gson 进行解析:
@Grab(group='com.google.code.gson', module='gson', version='2.8.5')
import com.google.gson.Gson
class Person {
String firstname
String lastname
}
def person = new Gson().fromJson('{"firstname": "Lando", "lastname": "Calrissian"}', Person.class)
assert person instanceof Person
println person.lastname