0

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

这是我尝试过的方法,但还没有成功。

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

文件 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

并且应用程序不会运行。

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

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

请帮忙!非常感谢!

4

3 回答 3

4

您通常不能在 Grails 工件的构造函数中做很多事情。您可以为此使用拦截器:

abstract class BaseController {
   protected String username

   def beforeInterceptor = {
      username = session.username
   }
}

这在http://grails.org/doc/latest/的第 6.1.5 节中有描述

于 2010-06-15T23:46:05.597 回答
0

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

于 2010-06-16T14:03:54.970 回答
0

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

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

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

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

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

于 2010-06-16T19:57:50.580 回答