I have tried to taste the new features of JSF 2.3, one attractive is the websocket.
I have read some sample codes from mojarra tests and JSF 2.3 specific @Push
javadoc.
And encountered some issues when used f:websocket
and f:ajax
.
The facelets template is:
<h:panelGroup id="messagePanel" layout="block">
<ul>
<ui:repeat value="#{ajaxBean.messages}" var="m">
<li>#{m}</li>
</ui:repeat>
</ul>
</h:panelGroup>
<h:form id="form">
<h:commandButton
id="sendMessage"
action="#{ajaxBean.sendMessage()}"
value="Send Ajax Message">
<f:ajax/>
</h:commandButton>
</h:form>
<h:form>
<f:websocket channel="ajaxChannel" scope="view">
<f:ajax event="ajaxEvent" render=":messagePanel" />
</f:websocket>
</h:form>
<h:form>
<f:websocket channel="ajaxListenerChannel" scope="view">
<f:ajax event="ajaxListenerEvent" listener="#{ajaxBean.ajaxPushed}" render=":messagePanel" />
</f:websocket>
</h:form>
<f:websocket channel="commandScriptChannel" scope="view" onmessage="onCommandScript"/>
<h:form>
<h:commandScript name="onCommandScript" action="#{ajaxBean.commandScriptExecuted()}" render=":messagePanel"/>
</h:form>
And backend bean is:
@ViewScoped
@Named("ajaxBean")
public class AjaxBean implements Serializable {
private static final Logger LOG = Logger.getLogger(AjaxBean.class.getName());
@Inject
@Push
PushContext ajaxChannel;
@Inject
@Push
PushContext ajaxListenerChannel;
@Inject
@Push
PushContext commandScriptChannel;
private List<String> messages = new ArrayList<>();
public void ajaxPushed(AjaxBehaviorEvent e) throws AbortProcessingException{
LOG.log(Level.INFO, "ajax pushed: " + e.toString());
messages.add("ajaxListenerEvent is sent at: " + LocalDateTime.now());
ajaxListenerChannel.send("ajaxListenerEvent");
}
public void commandScriptExecuted() {
LOG.log(Level.INFO, "commandScriptExecuted pushed.");
messages.add("commandScriptExecuted message is sent at: " + LocalDateTime.now());
commandScriptChannel.send("onCommandScript");
}
public void sendMessage() {
// LOG.log(Level.INFO, "ajax pushed by button: " + e.toString());
messages.add("ajaxEvent is sent at: " + LocalDateTime.now());
ajaxChannel.send("ajaxEvent");
}
public List<String> getMessages() {
return messages;
}
public void setMessages(List<String> messages) {
this.messages = messages;
}
}
The result is the first button can trigger the ajax output as needed. But f:ajax with a listener does not work, and h:commandScript also does not work here.
How to correct these?