Can I inject a service into a filter in Grails?

后端 未结 3 1203
不思量自难忘°
不思量自难忘° 2021-02-14 15:32

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 th

相关标签:
3条回答
  • 2021-02-14 16:04

    It looks like there are some problems with services in filters. This bug might point you in the right direction: https://jira.grails.org/browse/GRAILS-5982

    You can also try to get a reference to your service through the ApplicationContext. Here's an example: How do I get an instance of a Grails service programmatically?

    0 讨论(0)
  • 2021-02-14 16:19

    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).

    0 讨论(0)
  • 2021-02-14 16:20
    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
                    }
                }
            }
        }   
    }
    
    0 讨论(0)
提交回复
热议问题