【发布时间】:2018-10-16 12:44:00
【问题描述】:
在 Grails 应用程序的上下文中,我们将 JSON 解析为命令对象。从 JSON 映射到 POGO 的自动转换失败并出现如下错误:
org.codehaus.groovy.runtime.typehandling.GroovyCastException:
无法将具有类“groovy.json.internal.LazyMap”的对象“{<snip>}”转换为类“SomeCmd”,原因是:java.lang.IllegalArgumentException:没有枚举常量Foo.my-bar
我把范围缩小到这个普通的 Groovy MWE:
import groovy.json.JsonSlurper
enum Foo {
Bar("my-bar"),
Ista("my-ista")
final String s
private Foo(String s) {
this.s = s
}
}
class SomeCmd {
Foo foo
}
def some = new SomeCmd(new JsonSlurper().parseText('{ "foo" : "my-bar" }'))
println(some.foo)
这个错误与
java.lang.IllegalArgumentException: 没有枚举常量Foo.my-bar
这是意料之中的——到目前为止,一切都很好。
现在,在 the documentation 之后,我认为将自定义强制从 String 添加到 Foo 可能会解决问题(也来自 here):
enum Foo {
<snip>
static Foo fromJsonString(String s) {
return values().find { it.s == s }
}
}
def oldAsType = String.metaClass.getMetaMethod("asType", [Class] as Class[])
String.metaClass.asType = { Class type ->
type == Foo ?
Foo.byJsonString(delegate as String) :
oldAsType.invoke(delegate, [type] as Class[])
}
但是,错误仍然存在。显然,JsonSlurper 根本不使用强制,因为
println("my-bar" as Foo)
根据需要打印Bar。
这里发生了什么?我怎样才能让JsonSlurper 通过除了案例名称来选择正确的枚举案例?
PS:有趣的事实,如果我们将倒数第二行改为
new JsonSlurper().parseText('{ "foo" : "my-bar" }') as SomeCmd
脚本打印null。
【问题讨论】:
标签: json groovy enums mapping jsonslurper