2011-12-20 3 views
1

Griffon 용 HTTPBuilder 플러그인은 훌륭하며 내 서버 호출을 아주 잘 단순화합니다. 그러나 유일한 문제는 모든 장소에서 동일한 설정 코드를 계속 반복하지 않아도된다는 것입니다.내 자신의 메서드로 withRest()를 래핑하고 그 안에 클로저를 실행하는 이유는 무엇입니까?

내가하고 싶은 일은 동일한 연결 설정으로 서버 호출 집합과 다른 코드를 래핑하여 한 곳에서만 사용할 수 있도록하려는 것입니다. 예를 들어

이 내가 가진 무엇 :

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() 
    } 
} 

이 될해야 위대한은 일반적인 "설정/해제 리소스"코드를 단일 위치로 제거하고 포커스가 서버 호출의 고기 위에 있도록 허용하기 때문에 클로저에 사용합니다.

문제는 stmts()가 호출 될 때 나는 그것을 가지고 원하는대로 설정 한 코드를 실행하면, MissingMethodException의이 던져 때문에 제대로 추가되고있는 동적 방법처럼 보이지 않는다는 것입니다 :

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의 동적 메서드가 전달 된 클로저를 통해 제대로 연결되지 않았거나 그런 것입니다.

답변

3

클로저 대리자가 손실되는 것처럼 보입니다. 대리인은 그루비 폐쇄가 어떻게 작동하는지에있어 중요한 부분입니다. 각 클로저에는 연결된 대리자 개체가 있으며, 클로저 내에 호출 된 모든 메서드는 대리자에서 호출 할 수 있습니다. 정확한 순서는 Closure.setResolveStrategy으로 사용자 정의 할 수 있지만 기본값은 소유자 (클로저가 선언 된 위치)에서 먼저 메서드를 시도한 다음 대리자를 시도하는 것입니다. delegate으로 클로저 내에서 명시 적으로 대리자를 명시 적으로 참조 할 수 있습니다.

위임자는 setHeaders()과 같은 마법 동적 방법을 제공하기위한 주요 메커니즘입니다. HttpBuilder가 전달한 클로저를 호출하면 명시적인 클로저의 대리자가 설정되지만 stmts()은 건너 뜁니다. 위임자에게 stmts()으로 전달하면됩니다. 다음과 같이 시도하십시오.

def withMyRest(Closure stmts) { 
    withRest(uri: serverBaseURL) { 
     headers = requestHeaders 
     stmts.delegate = delegate 
     stmts() 
    } 
} 
+0

돈을 쓰면됩니다. ataylor가 제안한대로 대리인을 연결해야합니다. – aalmiray

+0

네, 이것이 제가 필요한 것입니다. 감사! – cdeszaq