我可以将服务注入Grails中的过滤器吗? [英] Can I inject a service into a filter in Grails?

查看:110
本文介绍了我可以将服务注入Grails中的过滤器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 创建名为'userService'的bean时出错:Scope'session'不是为当前线程激活

我的过滤器如下所示:

  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()?

解决方案

看起来问题在于你的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'引用,如果不是的话,您可能能够在resources.groovy中将userServiceSession重命名为userService(并相应地更新targetBeanName)。


I have a service to get and set the user in the session. I would like to pass in some user information to each view if there is a logged in user and thought a filter would be the best way so I don't have to duplicate that in every controller/action. When I run the app, it get this error:

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

My filter looks like this:

class SecurityFilters {
    def userService

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

I know I can just ultimately access the user through session.user, but I want to be able to call userService.isLoggedIn() which I can't easily through the view. So is there a way to inject the service into the filter, or should I just create a taglib to wrap userService.isLoggedIn()?

解决方案

It looks like the problem is your userService is scoped to the session, and there is not necessarily a session at the time the attempt to inject the service into the filter happens.

If your userService is necessarily session-scoped then you need to use a scoped proxy in your spring config. E.g. in 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
}

Then rename your injected variable in your SecurityFilter:

def userServiceSessionProxy

(and obviously rename where you use it elsewhere in the class).

What this should do is inject the proxy at injection time, but only go to the actual service at the time the filter is executed (when there is a session).

Note: not sure whether doing this still lets other places where there will be a session (e.g. controllers) still reference the service as 'userService', if not you might be able to rename userServiceSession to userService in resources.groovy (and update targetBeanName accordingly).

这篇关于我可以将服务注入Grails中的过滤器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆