1

Griffon 用の HTTPBuilder プラグインは優れており、サーバー呼び出しを非常に簡素化してくれます。ただし、唯一の問題は、同じセットアップ コードをあちこちで繰り返し続ける必要がないことです。

私がやりたいことは、一連のサーバー呼び出しと他のコードを同じ接続設定でラップして、1 か所だけに配置することです。

例として、これは私が持っているものです:

def persistCurrentSession() {
    withRest(uri: serverBaseURL) {
        headers = requestHeaders

        post(path: "${sessionBaseURL}${currentSession.id}",
                body: currentSession,
                requestContentType: groovyx.net.http.ContentType.JSON)
    }
}

def refreshCurrentSession() {
    withRest(uri: serverBaseURL) {
        headers = requestHeaders

        currentSession = get(path: "${sessionBaseURL}${currentSession.id}").responseData.sessionInstance
    }
}

そして、これが私がやりたいことです:

def persistCurrentSession() {
    withMyRest {
        post(path: "${sessionBaseURL}${currentSession.id}",
                body: currentSession,
                requestContentType: groovyx.net.http.ContentType.JSON)
    }
}

def refreshCurrentSession() {
    withMyRest {
        currentSession = get(path: "${sessionBaseURL}${currentSession.id}").responseData.sessionInstance
    }
}

def withMyRest(Closure stmts) {
    withRest(uri: serverBaseURL) {
        headers = requestHeaders
        stmts()
    }
}

Groovy とクロージャーについて私が知っていることから、これはクロージャーの優れた用途になるはずです。これにより、一般的な「リソースのセットアップ/破棄」コードが 1 か所に取り除かれ、サーバー呼び出しの本質に集中できるようになるからです。

問題は、動的メソッドが適切に追加されているように見えないことです。これは、必要な方法でコードを実行すると、呼び出さMissingMethodExceptionれたときに s がスローされるためです。stmts()

2011-12-20 11:12:40,097 [pool-2-thread-1] ERROR griffon.util.GriffonExceptionHandler - Uncaught Exception
org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingMethodException: No signature of method: client.MyAppServerService.post() is applicable for argument types: (java.util.LinkedHashMap) values: [[path:http://localhost:8080/Server/session/4, ...]]
Possible solutions: wait(), wait(long), print(java.lang.Object), use([Ljava.lang.Object;), is(java.lang.Object), split(groovy.lang.Closure)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:97)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1053)
    at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1071)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:883)
    at groovy.lang.Closure.call(Closure.java:410)
    at groovy.lang.Closure.call(Closure.java:404)
    at groovy.lang.Closure.run(Closure.java:488)
    at org.codehaus.griffon.runtime.util.AbstractUIThreadHandler$1.run(AbstractUIThreadHandler.java:41)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: groovy.lang.MissingMethodException: No signature of method: client.MyAppServerService.post() is applicable for argument types: (java.util.LinkedHashMap) values: [[path:http://localhost:8080/Server/session/4, ...]]
Possible solutions: wait(), wait(long), print(java.lang.Object), use([Ljava.lang.Object;), is(java.lang.Object), split(groovy.lang.Closure)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:78)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
    at client.MyAppServerService$_persistCurrentSession_closure2.doCall(MyAppServerService.groovy:49)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:226)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:52)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
    at client.MyAppServerService$_persistCurrentSession_closure2.doCall(MyAppServerService.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1053)
    at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1071)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:883)
    at groovy.lang.Closure.call(Closure.java:410)
    at groovy.lang.Closure.call(Closure.java:404)
    at java_util_concurrent_Callable$call.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at client.MyAppServerService$_withMyRest_closure4.doCall(MyAppServerService.groovy:71)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:226)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:52)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
    at client.MyAppServerService$_withMyRest_closure4.doCall(MyAppServerService.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1053)
    at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1071)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:883)
    at groovy.lang.Closure.call(Closure.java:410)
    at groovy.lang.Closure.call(Closure.java:404)
    at java_util_concurrent_Callable$call.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
    at java_util_concurrent_Callable$call.call(Unknown Source)
    at griffon.plugins.rest.RestConnector.doWithBuilder(RestConnector.groovy:90)
    at griffon.plugins.rest.RestConnector.this$2$doWithBuilder(RestConnector.groovy)
    at griffon.plugins.rest.RestConnector$this$2$doWithBuilder.callCurrent(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
    at griffon.plugins.rest.RestConnector$this$2$doWithBuilder.callCurrent(Unknown Source)
    at griffon.plugins.rest.RestConnector.withRest(RestConnector.groovy:67)
    at griffon.plugins.rest.RestConnector$withRest.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
    at griffon.plugins.rest.RestConnector$withRest.call(Unknown Source)
    at griffon.plugins.rest.RestConnector$_enhance_closure5.doCall(RestConnector.groovy:49)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod.invoke(ClosureMetaMethod.java:80)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoMetaMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:308)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:52)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:145)
    at client.MyAppServerService.withMyRest(MyAppServerService.groovy:68)
    at client.MyAppServerService$withMyRest.callCurrent(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
    at client.MyAppServerService.persistCurrentSession(MyAppServerService.groovy:48)
    at client.MyAppServerService$persistCurrentSession.callCurrent(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:137)
    at client.MyAppServerService.closeSession(MyAppServerService.groovy:41)
    at client.MyAppServerService$closeSession.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at client.StartController$_closure1_closure2.doCall(StartController.groovy:20)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:226)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:52)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
    at client.StartController$_closure1_closure2.doCall(StartController.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    ... 14 more

私がやろうとしていることを行うためのより良い方法があると確信していますが、それでも、私がやろうとしていることはうまくいくはずです. 私はまだGroovyにかなり慣れていませんが、スコープルールを何度も調べましたが、HTTPBuilderの動的メソッドが渡されたクロージャーを介して適切にアタッチされていないなどのことしか考えられません。

4

1 に答える 1

3

クロージャー デリゲートが失われつつあるようです。デリゲートは、Groovy クロージャーがどのように機能するかの重要な部分です。各クロージャーにはデリゲート オブジェクトが関連付けられており、クロージャー内で呼び出されるメソッドはデリゲートで呼び出すことができます。正確な順序はClosure.setResolveStrategyでカスタマイズできますが、デフォルトでは、最初に所有者 (クロージャが宣言されている場所) でメソッドを試行し、次にデリゲートで試行します。を使用して、クロージャー内でいつでもデリゲートを明示的に参照できますdelegate

デリゲートは、 のような魔法の動的メソッドを提供するための主要なメカニズムですsetHeaders()。HttpBuilder が渡されたクロージャーを呼び出すと、明示的なクロージャーのデリゲートが設定されますが、stmts()スキップされます。デリゲートを に渡すだけですstmts()。次のようなことを試してください:

def withMyRest(Closure stmts) {
    withRest(uri: serverBaseURL) {
        headers = requestHeaders
        stmts.delegate = delegate
        stmts()
    }
}
于 2011-12-20T18:08:15.313 に答える