如何访问Grails中基本控制器的构造函数中的控制器动态属性?

时间:2010-06-15 22:35:21

标签: model-view-controller groovy grails grails-controller

基本上,我希望能够将过滤器中创建的对象分配给每个控制器扩展的基本控制器中的成员。有可能这样做吗?

这是我尝试的方式,但没有让它发挥作用。

我想要实现的是让我的所有控制器都扩展一个基本控制器。基本控制器的构造函数将用于为其成员分配值,这些值是从会话映射中提取的。示例如下。

文件grails-app / controllers / HomeController.groovy:

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

文件grails-app / controllers / 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

该应用程序将无法运行。

这只是一个例子,因为在我的情况下,我不想为字符串值分配用户名,而是从会话地图中提取一些对象。从会话地图中提取的对象正在过滤器中设置。

我看到的替代方案是能够在过滤器的执行中访问控制器的实例。这可能吗?

请帮忙!非常感谢!

3 个答案:

答案 0 :(得分:4)

您通常无法在Grails工件的构造函数中做很多事情。你可以使用拦截器:

abstract class BaseController {
   protected String username

   def beforeInterceptor = {
      username = session.username
   }
}

http://grails.org/doc/latest/

的第6.1.5节对此进行了描述

答案 1 :(得分:0)

您可以使用请求范围的服务...

答案 2 :(得分:0)

作为一项规则,我要小心不要将状态直接放在控制器中;一般而言(无论框架如何)控制器通常都是无状态的。我坚持使用标准的webapp状态构造,如请求和会话来存储和传输数据。

对于您的具体情况,我会执行以下操作之一:

  • 如果是轻量级数据(基元),我会将它们存储在会话中,并根据需要访问它们:
    例如渲染session.username

  • 如果是动态或数据库驱动的数据,我会根据需要创建服务并提取数据: 例如homeService.getUser()。用户名

  • 作为上述与Burt讨论的变体,您可以使用过滤器来填充请求或会话值。