我可以将服务注入Grails的过滤器吗?

时间:2010-09-29 22:28:53

标签: grails

我有一个服务来获取和设置会话中的用户。如果有登录用户,我想将一些用户信息传递给每个视图,并认为过滤器是最好的方式,所以我不必在每个控制器/动作中复制它。当我运行应用程序时,它会收到此错误:

Error creating bean with name 'userService': Scope 'session' is not active for the current thread

我的过滤器如下所示:

class SecurityFilters {
    def userService

    def filters = {
        setUser(controller:'*', action:'*') {
            before = {
                if (userService.isLoggedIn()) {
                    request.user = userService.getUser()
                } else {
                    request.user = null
                }
            }
        }
    }   
}

我知道我最终可以通过session.user访问用户,但我希望能够调用userService.isLoggedIn(),这是我无法通过视图轻松完成的。那么有没有办法将服务注入过滤器,或者我应该创建一个taglib来包装userService.isLoggedIn()?

3 个答案:

答案 0 :(得分:9)

看起来问题是你的userService是作用于会话的,并且在尝试将服务注入过滤器时不一定会有会话。

如果您的userService必须是会话范围的,那么您需要在spring配置中使用范围代理。例如。在grails-app / conf / spring / resources.groovy:

import com.your.service.UserService
...
userServiceSession(UserService)
{ bean ->
    bean.scope = 'session'
}
userServiceSessionProxy(org.springframework.aop.scope.ScopedProxyFactoryBean)
{
    targetBeanName = 'userServiceSession'
    proxyTargetClass = true
}

然后在SecurityFilter中重命名您注入的变量:

def userServiceSessionProxy

(显然重命名你在课堂的其他地方使用它。)

这应该做的是在注入时注入代理,但只在执行过滤器时(当有会话时)转到实际服务。

注意:不确定这样做是否仍然允许会话的其他地方(例如控制器)仍然将服务引用为“userService”,否则您可能能够在资源中将userServiceSession重命名为userService。 groovy(并相应地更新targetBeanName)。

答案 1 :(得分:2)

看起来过滤器中的服务存在一些问题。这个错误可能会指向正确的方向:https://jira.grails.org/browse/GRAILS-5982

您还可以尝试通过ApplicationContext获取对您服务的引用。这是一个例子:How do I get an instance of a Grails service programmatically?

答案 2 :(得分:0)

import org.codehaus.groovy.grails.web.context.ServletContextHolder
import org.springframework.context.ApplicationContext
import org.springframework.web.context.support.WebApplicationContextUtils
class SecurityFilters {
    def userService

    def filters = {
        setUser(controller:'*', action:'*') {
            before = {
                def servletCtx = ServletContextHolder.getServletContext()
                ApplicationContext applicationContext = WebApplicationContextUtils.
                    getRequiredWebApplicationContext(servletCtx)
                userService =applicationContext.getBean('userService')
                if (userService.isLoggedIn()) {
                    request.user = userService.getUser()
                } else {
                    request.user = null
                }
            }
        }
    }   
}