1

Grails アプリケーションのコンテキストでは、JSON をコマンド オブジェクトに解析します。JSON マップから POGO への自動変換は、次のようなエラーで失敗します。

org.codehaus.groovy.runtime.typehandling.GroovyCastException:クラス ' ' のオブジェクト ' ' をクラス ' ' に
キャストできません: : 列挙定数がありません{<snip>}groovy.json.internal.LazyMapSomeCmd
java.lang.IllegalArgumentExceptionFoo.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

これは予想どおりです。これまでのところ、非常に良好です。

さて、ドキュメンテーションに従って、からカスタム強制を追加すると問題が解決する可能性がある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: 興味深いことに、最後から 2 番目の行を次のように変更すると、

new JsonSlurper().parseText('{ "foo" : "my-bar" }') as SomeCmd

スクリプトは を出力しnullます。

4

1 に答える 1

0

Groovy は喜んでカスタム セッターを使用してオブジェクトを構築します。質問にあるように、次のようFoo.fromJsonStringに定義します。SomeCmd

class SomeCmd {
    Foo foo

    void setFoo(Object jsonObject) {
        if (jsonObject == null || jsonObject instanceof Foo) {
            this.foo = jsonObject
            return
        } else if (jsonObject instanceof String) {
            Foo f = Foo.fromJsonString(jsonObject)
            if ( null != f ) {
                this.foo = f
                return
            }
        }

        throw new IllegalArgumentException("No Foo for $jsonObject")
    }
}

次に、指定されたコードが必要に応じて印刷Barされます。

ただし、これは JSON をコマンド オブジェクトに解析する Grails では役に立ちません。Grails は強制も Groovy のマップ「マジック」も使用しません。このフォローアップの質問を参照してください。

于 2018-11-06T09:59:18.743 に答える