我正在尝试使用Java EE 7创建交互式聊天Web应用程序,特别是使用带有ajax的JSF 2.2。
这个想法是总是有一个缓慢的等待异步ajax请求等待 在服务器上为每个客户端。一旦新消息到达服务器, 返回所有等待请求,以便在所有客户端中呈现消息。 完成请求后,客户端将发送新的等待请求。 如果在30秒内没有消息到达,则返回请求以使其成为新消息 可以在旧的一次之前提交。
我可以让它像这样工作:
的index.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>async jsf app</title>
<h:outputScript library="js" name="resendscript.js" />
</h:head>
<h:body>
async jsf app
<h:form id="jsfappform">
say something:
<h:inputText id="newmsg" value="#{jsfAsync.newMessage}" />
<h:commandButton id="sendbut" value="say" action="#{jsfAsync.say}" />
<br /><br />
Messages:
<br /><br />
<h:outputText id="msgs" value="#{jsfAsync.msgs}" escape="false">
<h:outputScript>resendRequest()</h:outputScript>
</h:outputText>
<h:commandButton id="reloadbut" value="" action="#{jsfAsync.resend}" style="visibility: hidden">
<f:ajax execute="@this" render="msgs" onevent="handleAjax" onerror="handleError" />
</h:commandButton>
<h:commandButton id="clearbut" value="clear" action="#{jsfAsync.clear}" />
<h:outputScript>resendRequest()</h:outputScript>
</h:form>
</h:body>
</html>
resendscript.js:
function handleAjax(data)
{
var status = data.status;
switch(status)
{
case "success": resendRequest();
break;
}
}
function handleError(data) { }
function resendRequest()
{
document.getElementById("jsfappform:reloadbut").click();
}
支持bean JsfAsync.java:
package jsfasync;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ApplicationScoped;
@ManagedBean
@ApplicationScoped
public class JsfAsync
{
private final List<String> messages;
private final Object wakeup;
public JsfAsync()
{
wakeup = new Object();
messages = new ArrayList<String>();
}
public void setNewMessage(String msg)
{
synchronized(messages) { messages.add(msg); }
}
public void say()
{
synchronized(wakeup) { wakeup.notifyAll(); }
}
public void resend()
{
try {
synchronized(wakeup) { wakeup.wait(30000); }
} catch (Exception e) { }
}
public void clear()
{
synchronized(messages) { messages.clear(); }
say();
}
public String getNewMessage() { return ""; }
public String getMsgs()
{
StringBuilder msgs = new StringBuilder();
synchronized(messages)
{
for (String m : messages)
{
msgs.append(m);
msgs.append("<br />");
}
return msgs.toString();
}
}
}
我想用ajax请求API替换 resendRequest() javascript函数的主体,如下所示:
jsf.ajax.request('jsfappform:reloadbut', null,
{'javax.faces.behavior.event': 'action',
'execute': 'jsfappform:reloadbut',
'render': 'jsfappform:msgs',
'onevent': 'handleAjax',
'onerror': 'handleError'});
不幸的是,我无法以这种方式工作。该调用可以执行ajax请求,但似乎忽略了 onevent 选项,并且在此请求完成时未调用事件处理程序。或许,您是否有任何提示如何使其以这种方式运作?
答案 0 :(得分:3)
对于提示,请检查生成的<h:commandButton id="reloadbut">
HTML源代码。您将看到JSF已将其生成为'onevent': handleAjax
。实际上,作为函数引用而不是字符串。
相应修复:
jsf.ajax.request('jsfappform:reloadbut', null,
{'javax.faces.behavior.event': 'action',
'execute': 'jsfappform:reloadbut',
'render': 'jsfappform:msgs',
'onevent': handleAjax,
'onerror': handleError});