There is a JSF 1.2 page with <rich:messages>
and <a4j:poll>
components on it. When a message is placed in FacesContext
开发者_运维百科it is only shown briefly, until the poll sends the next request. Is it possible to preserve messages across AJAX requests?
Possible, but you would need to save the message yourself. Messages in JSF are request scoped, and thus cleared between requests.
Add the following to your facelets:
<ui:define name="metadata">
<f:event type="preRenderView" listener="#{ajaxBacking.displayMessages}" />
</ui:define>
Create a backing bean to persist the messages through ajax calls:
@ManagedBean
@ViewScoped
public class AjaxBacking {
Map<String, List<FacesMessage>> messages;
public AjaxBacking(){
messages = new HashMap<String, List<FacesMessage>>();
}
public static AjaxBacking getCurrentInstance() {
AjaxBacking ajaxBacking = null;
FacesContext context = FacesContext.getCurrentInstance();
if ((ajaxBacking = (AjaxBacking) context.getViewRoot().getViewMap().get("ajaxBacking")) == null){
ajaxBacking = (AjaxBacking)context.getApplication().evaluateExpressionGet(context,"#{ajaxBacking}",AjaxBacking.class);
}
return ajaxBacking;
}
public void displayMessages(){
FacesContext facesContext = FacesContext.getCurrentInstance();
for (String component : messages.keySet()){
for (FacesMessage message : messages.get(component)) {
if (!facesContext.getMessageList(component).contains(message)){
facesContext.addMessage(component, message);
}
}
}
}
public void putMessages(String component, List<FacesMessage> facesMessage){
List<FacesMessage> messages = new ArrayList<FacesMessage>();
for (FacesMessage message : facesMessage) messages.add(message);
this.messages.put(component, messages);
}
public Map<String, List<FacesMessage>> getMessages() {
return messages;
}
}
And finally add this line to the bottom of any bean method that adds a FacesMessage.
AjaxBacking.getCurrentInstance().putMessages(messages,facesContext.getMessageList(messages);
精彩评论