2010-06-15 3 views
0

기본적으로 모든 컨트롤러가 확장되는 기본 컨트롤러의 멤버에게 필터 내에서 만들어진 개체를 할당 할 수 있기를 원합니다. 그렇게 할 수있는 방법은 없나요?Grails의 기본 컨트롤러 생성자에서 컨트롤러 동적 속성에 액세스하는 방법은 무엇입니까?

다음은 내가 시도한 방법이지만 작동하게 만들지 않았습니다.

내가 얻으려고하는 것은 모든 컨트롤러가 기본 컨트롤러를 확장하도록하는 것입니다. 기본 컨트롤러의 생성자는 세션 맵에서 가져온 값을 멤버에 할당하는 데 사용됩니다. 아래 예.

파일 Grails는-응용 프로그램/컨트롤러/HomeController.groovy :

class HomeController extends BaseController { 
    def index = { 
     render username 
    } 
} 

파일 Grails는-응용 프로그램/컨트롤러/BaseController.groovy :

abstract class BaseController { 
    public String username 

    public BaseController() { 
     username = session.username 
    } 
} 

응용 프로그램을 실행 표시된 출력은 다음과 같습니다

2010-06-15 18:17:16,671 [main] ERROR [localhost].[/webapp] - Exception sending context initialized event to listener instance of class org.codehaus.groovy.grails.web.context.GrailsContextLoaderListener 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.RuntimeException: Unable to locate constructor with Class parameter for class org.codehaus.groovy.grails.commons.DefaultGrailsControllerClass 
    ... 
Caused by: java.lang.RuntimeException: Unable to locate constructor with Class parameter for class org.codehaus.groovy.grails.commons.DefaultGrailsControllerClass 
    ... 
Caused by: java.lang.reflect.InvocationTargetException 
    ... 
Caused by: org.codehaus.groovy.grails.exceptions.NewInstanceCreationException: Could not create a new instance of class [com.my.package.controller.HomeController]! 
    ... 
Caused by: groovy.lang.MissingPropertyException: No such property: session for class: com.my.package.controller.HomeController 
    at com.my.package.controller.BaseController.<init>(BaseController.groovy:16) 
    at com.my.package.controller.HomeController.<init>(HomeController.groovy) 
    ... 
2010-06-15 18:17:16,687 [main] ERROR core.StandardContext - Error listenerStart 
2010-06-15 18:17:16,687 [main] ERROR core.StandardContext - Context [/webapp] startup failed due to previous errors 

그리고 앱이 실행되지 않습니다.

내 경우에는 문자열 값에 사용자 이름을 할당하고 싶지 않고 세션 맵에서 가져온 개체가 약간 있습니다. 세션 맵에서 가져온 개체가 필터 내에 설정됩니다.

내가 볼 수있는 대안은 필터의 실행 내에서 컨트롤러의 인스턴스에 액세스 할 수 있다는 것입니다. 그게 가능하니?

도와주세요! 무리 감사!

답변

4

일반적으로 Grails 아티팩트의 생성자에서는 많은 작업을 수행 할 수 없습니다. 나는 ', 원칙적으로

+0

답변 해 주셔서 감사합니다. 이 문제는 구체적인 컨트롤러 (HomeController)가 beforeInterceptor 자체를 정의하고 BaseController의 beforeInterceptor가 호출되지 않을 때 발생합니다. 콘트롤러를 통해 'super.beforeInterceptor()'를 사용하여 호출하려고 시도하지만, 런타임시이를 던집니다. org.codehaus.groovy.runtime.InvokerInvocationException : java.lang.StackOverflowError \t at java.lang.Thread.run com.my.package.controller.HomeController $ _closure1.doCall (HomeController.groovy) 그 문제를 해결하는 \t ... 어떤 방법에 java.lang.StackOverflowError의 \t :에 의해 발생 (Thread.java:619) ? 감사! – djule5

+2

클로저이기 때문에 super.beforeInterceptor()는 작동하지 않습니다. 그러나 대체 할 수있는 실제 메소드에 대한 인터셉터 위임을 가질 수 있습니다. def beforeInterceptor = {prepareCall()} protected void prepareCall() {username = session.username} –

0

의 섹션 6.1.5에 설명되어

abstract class BaseController { 
    protected String username 

    def beforeInterceptor = { 
     username = session.username 
    } 
} 

: 당신이 생각에 대한 요격을 사용할 수 있습니다 컨트롤러에 직접 상태를 두는 것에 대한주의; 일반적으로 컨트롤러 (프레임 워크와 상관없이)는 일반적으로 무국적자를 지향합니다. 나는 요청 및 세션과 같은 표준 webapp 상태 구성을 사용하여 데이터를 저장하고 전송할 것입니다.

  • 을 경량 데이터 (프리미티브), 내가 세션에 저장하고 단지 필요에 따라 액세스하려는 경우 :
    예를 들어, 특정 사례를 들어

    , 나는 다음 중 하나를 수행 할 것 render session.username

  • 동적 또는 데이터베이스 기반 데이터 인 경우 서비스를 만들고 필요에 따라 데이터를 가져옵니다. 예 : homeService.getUser(). username

  • 위의 Burt와의 토론을 변형하여 필터를 사용하여 요청이나 세션 값을 채울 수 있습니다.

관련 문제