Groovy 从JsonSlurper向对象添加强类型

Groovy 从JsonSlurper向对象添加强类型,groovy,typing,jsonslurper,Groovy,Typing,Jsonslurper,我在Groovy中使用JsonSlurper进行键入时遇到了一些问题。我对Groovy是相当陌生的,甚至在向它添加强类型方面更是新手——请耐心听我说 现在我已经创建了一个trait,它定义了我的JSON对象的一般形状,我正试图将parseText的结果转换到它 import groovy.json.JsonSlurper trait Person { String firstname String lastname } def person = (Person)(new Js

我在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将尝试将您的映射转换为所述对象

从:

强制运算符(as)是强制转换的一种变体。强制将对象从一种类型转换为另一种类型,而不兼容赋值

POJO的工作方式是使用Map-c'tor构造一个新对象。这将展开到调用setter中,或者直接用于静态编译

请注意,使用带有多余关键点的贴图将导致错误。所以我只会把它用在玩具项目上。使用合适的JSON映射器,例如Jackson

因此,这里的解决方案是不使用trait(基本上是一个接口),而是使用常规类。

这实际上是一个cast,Groovy将尝试将您的映射转换为所述对象

从:

强制运算符(as)是强制转换的一种变体。强制将对象从一种类型转换为另一种类型,而不兼容赋值

POJO的工作方式是使用Map-c'tor构造一个新对象。这将展开到调用setter中,或者直接用于静态编译

请注意,使用带有多余关键点的贴图将导致错误。所以我只会把它用在玩具项目上。使用合适的JSON映射器,例如Jackson


因此,这里的解决方案不是使用trait(基本上是一个接口),而是使用常规类。

您可以尝试使用delegate

这允许将类包装在地图上

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

您可以尝试使用委托

这允许将类包装在地图上

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

使用
而不是
特征
作为奖励,可以使cast与
JsonSlurper
一起工作,因为cast可以正确实例化对象。使用
而不是
特征
作为奖励,可以使cast与
JsonSlurper
一起工作,因为cast可以正确实例化对象