我可以将服务注入Grails中的过滤器吗?
我有一个服务来获取和设置会话中的用户。如果有登录的用户,我想向每个视图传递一些用户信息,并认为过滤器是最好的方式,因此我不必在每个控制器/操作中重复这些信息。当我运行应用程序时,它会出现以下错误:我可以将服务注入Grails中的过滤器吗?,grails,Grails,我有一个服务来获取和设置会话中的用户。如果有登录的用户,我想向每个视图传递一些用户信息,并认为过滤器是最好的方式,因此我不必在每个控制器/操作中重复这些信息。当我运行应用程序时,它会出现以下错误: Error creating bean with name 'userService': Scope 'session' is not active for the current thread 我的过滤器如下所示: class SecurityFilters { def userServi
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()?过滤器中的服务似乎存在一些问题。此错误可能会为您指明正确的方向:
您还可以尝试通过
ApplicationContext
获取对您的服务的引用。下面是一个示例:问题似乎在于您的用户服务的作用域是会话,并且在尝试将服务注入筛选器时不一定存在会话
如果您的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”,如果不是,您可能可以在resources.groovy中将userServiceSession重命名为userService(并相应地更新targetBeanName) 这听起来是一个有效的解决方案,但我选择了切换到taglib。看起来更简单,答案是不行。我添加了一条明显被删除的评论,说我不能,并提供了一种不同的方法。
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
}
}
}
}
}