2010-09-29 13 views
8

Ho un servizio per ottenere e impostare l'utente nella sessione. Vorrei passare alcune informazioni utente a ciascuna vista se c'è un utente che ha effettuato l'accesso e ho pensato che un filtro sarebbe il modo migliore, quindi non devo duplicarlo in ogni controller/azione. Quando eseguo l'applicazione, si ottiene questo errore:Posso iniettare un servizio in un filtro in Grails?

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

mio filtro simile a questa:

class SecurityFilters { 
    def userService 

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

So che posso solo in ultima analisi, accedere l'utente attraverso session.user, ma voglio essere in grado di chiamare userService.isLoggedIn() che non riesco facilmente a visualizzare. Quindi c'è un modo per iniettare il servizio nel filtro, o dovrei semplicemente creare un taglib per avvolgere userService.isLoggedIn()?

+0

Bene, la risposta era no, non posso. Ho aggiunto un commento che apparentemente è stato cancellato dicendo che non potevo e fornito un approccio diverso. – varikin

risposta

9

Sembra che il tuo userService sia collegato alla sessione e non ci sia necessariamente una sessione nel momento in cui si verifica il tentativo di iniettare il servizio nel filtro.

Se userService è necessariamente con scope di sessione, è necessario utilizzare un proxy con scope nella configurazione di primavera. Per esempio. in graal-app/conf/primavera/resources.groovy:

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

quindi rinominare la variabile iniettato nel vostro SecurityFilter:

def userServiceSessionProxy 

(e, ovviamente, rinominare in cui lo si utilizza altrove nella classe).

Ciò che dovrebbe fare è iniettare il proxy al momento dell'iniezione, ma solo andare al servizio effettivo nel momento in cui viene eseguito il filtro (quando c'è una sessione).

Nota: non so se facendo questo lascia ancora altri posti in cui ci sarà una sessione (ad esempio i controller) ancora fare riferimento al servizio come 'userService', se non si potrebbe essere in grado di rinominare userServiceSession a userService in resources.groovy (e aggiorna targetBeanName di conseguenza).

+0

Sembra una soluzione valida, ma ho optato invece per passare a un taglib. Sembrava più semplice. – varikin

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 
       } 
      } 
     } 
    } 
} 
Problemi correlati