В контексте приложения Grails мы разбираем JSON на объекты команд.Автоматическое преобразование из карты JSON в POGO завершается неудачно с такой ошибкой:
org.codehaus.groovy.runtime.typehandling.GroovyCastException
:
Невозможно привести объект '{<snip>}
' с классом 'groovy.json.internal.LazyMap
' к классу'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)
Thisошибки с
java.lang.IllegalArgumentException
: нет константы перечисления Foo.my-bar
Это ожидается - пока, так хорошо.
Теперь, после документация , я думал, что добавление пользовательского принуждения с String
до Foo
может решить проблему (также с здесь ):
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
.