Server-side initiation: EJB & # 8594; FacesContext?
I already asked this question on the Icefaces forum, but in the meantime I realized that this is a more general problem.
I want to update parts of the JSF page when I get a message in my MDB.
The problem is how do I get the FacesContext from the EJB container?
In the message handling function FacesContext.getCurrentInstance () returns null.
I also tried to make a JSF managed bean be MDB, but I couldn't (you can't seem to have both in the same class?).
Since I'm new to the JSF world, I'm stuck right now. Is there a way to make it work?
(Glassfish v3 + Netbeans 6.8, JSF2 + Icefaces 2.0 alpha2)
a source to share
FacesContext is based on an HTTP request and is therefore only available while the HTTP request is being processed, and even when the request URL matches the FacesServlet URL pattern. Unless you are inside the thread that the server is executing to process the HTTP request, then there are also no FacesContext facilities. The EJB container has no HTTP request facility at all.
Technically, the only way to let the EJB tell JSF about a new message is to let the EJB fire an HTTP request on a URL that matches the FacesServlet URL pattern with the message as a request parameter. You can use java.net.URLConnection
for this. JSF, in turn, can then execute comet / HTTP push stuff to update the view with IceFaces post as you mentioned.
eg.
URL url = new URL("http://example.com/context/poll.jsf?msg=" + URLEncoder(msg, "UTF-8"));
URLConenction connection = url.openConnection();
InputStream response = connection.getInputStream();
and a poll.jsf
that are attached to the base bean like this:
@ManagedBean
public class Poll {
@ManagedProperty(value="#{param.msg}")
private String msg;
@PostConstruct
public void init() {
// Do something with msg.
}
public void setMsg(String msg) {
this.msg = msg;
}
}
Note: using JSF 2.0 annotations, but they should be self explanatory enough.
a source to share
I'm not an expert, but I would expect the FacesContext to be available only while the JSF request is being processed. I'm afraid you may not be able to do exactly what you want, but you can certainly get around it. There are actually two problems:
- How do I get an update via MDB to a JSF page?
- How do I refresh the page on the client when an event occurs? You usually cannot send data from the server to the client, the client must (although there are some workarounds such as http://en.wikipedia.org/wiki/Comet_(programming) ))
I need the following:
- The MDB stores the updated data somewhere - for example in the global cache (stateless session bean with @Singleton and collection or map for updates)
- Modify the JSF page so that it asks the server for updates at regular intervals (preferably in the background using Ajax through some ajax enabled JSF component) - if there is an update received via MDB the server will return it and the page will re-render itself
a source to share
I have a workaround that includes a timer on the JSF side (luckily, this is server only, no AJAX and client-server communication required) that checks the Singleton and updates updates as needed. However, I still believe that this is not the right solution and that it can be done without a timer ...
a source to share