Splitting Components Between Views - How To Improve My Design?
I am working on a JSF web application that aims to wrap a command line program. One of its main features is the ability to share a session between users (for example, for course purposes) so that when input is sent to an application instance, output is sent to each subscriber for that session.
As a result of this construction, the webapp basically consists of a bean with a view that will request the controller of the command line application. A session definition with a URL fragment was also chosen (e.g. mydomain / myapp / # SESSIONID) so that anyone using a URL with the same fragment will share the ins and outs using their own view instance -scoped bean, but sharing the same controller
To push results to all subscribers, I use Primefaces Push. The results are primarily text to be attached to the webapp terminal, but some commands lead to programmatically creating the JSF component. To deal with this, I simply pass these components to a string that I send to all subscribers.
Then I realized that in order to handle ajax requests from components (and from each subscriber) the corresponding UIComponent needs to be added to the UIViewRoot in the context (not sure how to express this) each view is a scope bean.
In fact I first tried to bind a "shared container" (UIForm) to a bean scope property where I would put programmatically generated components, but I obviously had to run into a chicken / egg issue @BalusC talks about his blog because the component was added again in every ajax request. Setting it javax.faces.PARTIAL_STATE_SAVING
to false didn't help either (I'm using MyFaces 2.2.5)
So, as some workaround, when the controller needs to create a new bean, it basically adds the bean id to the pushed data (in a HashMap converted to Json) and all subscribers will fire (back) the remoteCommand to its own bean scope instance. to update the "shared container" from its own UIViewRoot.
It works, but I don't like it!
So:
-
Is it possible to handle this kind of sharing between scoped beans (of the same name) that are stored across different HTTP sessions? I am referencing this answer from @BalusC ... perhaps playing around with
javax.faces.ViewState
- is it possible? -
Is there a "magic" scope for my current bean view that I could use?
-
Should I be using a completely different design?
Thank!
source to share
If you want to share data among all users of your application, you can use the scope.
If you still want to use the view scope, you can associate your scope with another application scope like this:
ApplicationView appView = BeanUtil.findBean("applicationView", FacesContext.getCurrentInstance());
import javax.faces.context.FacesContext;
public class BeanUtil {
@SuppressWarnings("unchecked")
public static <T> T findBean(String beanName, FacesContext context) {
return (T) context.getApplication().evaluateExpressionGet(context,
"#{" + beanName + "}", Object.class);
}
}
source to share