Могу ли я добавить сервис в фильтр в Grails? - PullRequest
8 голосов
/ 30 сентября 2010

У меня есть служба для получения и установки пользователя в сеансе. Я хотел бы передать некоторую информацию о пользователях каждому представлению, если есть вошедший в систему пользователь и считает, что фильтр будет лучшим способом, поэтому мне не нужно дублировать это в каждом контроллере / действии. Когда я запускаю приложение, оно получает эту ошибку:

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 ]

9 голосов
/ 30 сентября 2010

Похоже, проблема в том, что ваша userService ограничена сеансом, и в то время, когда попытка внедрить службу в фильтр не обязательно является сеансом.

Если ваш userService обязательно является сеансом-scoped тогда вам нужно использовать прокси-сервер scoped в вашем весеннем конфиге.Например, в 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 в resources.groovy (и обновите targetBeanName соответственно).

2 голосов
/ 30 сентября 2010

Похоже, есть проблемы с сервисами в фильтрах.Эта ошибка может указывать вам правильное направление: https://jira.grails.org/browse/GRAILS-5982

Вы также можете попытаться получить ссылку на свой сервис через ApplicationContext.Вот пример: Как получить экземпляр службы Grails программно?

0 голосов
/ 04 сентября 2013
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
                }
            }
        }
    }   
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...