Pergunta

Which of the following methods is considered the recommended way of storing data in grails for the duration of a users session?

  1. Store a bunch of individual variables in the actual session.
  2. Store a domain model class object in the session.
  3. Use a session scoped controller and store the variables as controller fields or properties.
  4. Use a session scoped controller and store the data as a domain model class object stored in the controller.
  5. Some other way that I have not thought of yet.
Foi útil?

Solução

I like to use session-scoped services for this sort of thing. With this approach you inject a proxy for your session scoped service into a globally scoped service (or controller), which means you don't need to worry about keeping track of the stuff you put into the session.

There's a nice little tutorial here that shows you how to mix differently-scoped services. And it looks like the author of that tutorial has also written a plugin to make the process easier (I haven't actually tried the plugin though).

EDIT:

Here's an example showing how you'd set this up & actually use a service proxy to pass stuff to your view:

Create a service that's going to hold your session-scoped stuff, like a user shopping cart or whatever. It's just a regular service (that references other services etc), but you can store session-specific stuff as member variables -

class MySessionScopedService {

    def currentUser
    def shoppingCart

    ...

}

In resources.groovy, set up a session-scoped proxy for your service. Rather than directly injecting MySessionScopedService into other services, you'll be injecting a proxy for it.

beans = {
    mySessionScopedServiceProxy(org.springframework.aop.scope.ScopedProxyFactoryBean) {
        targetBeanName = 'mySessionScopedService'
        proxyTargetClass = true
    }
}

Finally, when you want to reference your service, you reference the proxy (notice I'm referencing mySessionScopedServiceProxy rather than mySessionScopedService). You can reference the proxy in any globally-scoped component and at runtime, Spring will inject the correct one for the current session.

class MyController {
    def mySessionScopedServiceProxy
    def someOtherService

    def index() {
        [shoppingCart: mySessionScopedServiceProxy.shoppingCart, currentUser: mySessionScopedServiceProxy.currentUser]
    }
}

Outras dicas

As sudhir already pointed out, a map stored directly in the session is for me the easiest and most expected way.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top