Gerald Müllan wrote:
you have to make sure every time to make a phaseListener thread safe.
Means it is shared by all user among the incoming requests.
A PL for only one user in only one session is not the way it works..
Yep. If you want to get "per-page" callbacks to a backing bean (rather
than callbacks triggered by components) then a PhaseListener is *not*
the right solution (at least not without a lot of extra clever stuff).
As Gerald notes, PhaseListener classes are application-wide (shared by
all users); it can use FacesContext.getCurrentInstance to determine the
right context for the current user, but cannot easily determine what
backing bean methods to then invoke.
The Apache Shale library has one solution, the "view controller" module.
It does use a PhaseListener, but also hooks the ViewHandler and various
other bits to provide the phase listener with enough info to figure out
what beans to invoke. It's still a pretty limited solution in many ways
though.
The project I'm currently working on initially used a
PhaseListener-based approach for "per-page" callbacks, where the
PhaseListener used a list of managed beans stored in a session-scope
attribute to determine what callbacks to make This turned out to be
fundamentally flawed. I've recently replaced this with another approach:
a custom component that has "onRender" and "onPostback" attributes that
are method bindings. On call to its processDecodes method it invokes the
onPostback method binding (if any), and on encodeBegin it invokes the
onRender method binding (if any). For any page where an associated
backing bean needs page-related callbacks, this tag can just be added to
the page. It's pretty simple and very effective so far. It handles pages
that are composed of separate fragments using includes much more
elegantly than the shale approach for example. It also keeps
page-relevant configuration in the page rather than in the faces config
file. I think a component like this could be a useful addition to tomahawk.
Regards,
Simon