我在应用程序中遇到多窗口处理问题。 我目前使用Conversation Scope来启用多窗口/选项卡处理,但是如果用户在新选项卡中打开链接(按钮),则会在新旧选项卡之间共享对话。
Apache Deltaspike有一个解决方案(http://deltaspike.apache.org/documentation/#_module_overview),但我已经使用了Seam 3(和JSF 2.1)并且不想迁移到Deltaspike。
所以我正在寻找没有Deltaspike的替代解决方案,还是可以使用Deltaspike和Seam 3?
答案 0 :(得分:0)
我用p:remoteCommand构建了一个解决方案,这个答案是:In javascript, how can I uniquely identify one browser window from another which are under the same cookiedbased sessionId
我将这个JS添加到我的模板中,该模板为每个浏览器选项卡创建一个唯一的ID,并将其存储在window.name中。然后它调用一个p:remoteCommand来检查guid:
$(window).load(function() {
// ----------------------
var GUID = function() {
// ------------------
var S4 = function() {
return (Math.floor(Math.random() * 0x10000 /* 65536 */
).toString(16));
};
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
};
if (!window.name.match(/^GUID-/)) {
window.name = "GUID-" + GUID();
}
if ($('#guid_form\\:server_guid').text().length == 0 ||
$('#guid_form\\:server_guid').text() != window.name) {
checkGuid([{name:'guid', value:window.name}]);
}
})
在我的模板中添加了一个Primefaces remoteCommand,由上面的脚本调用。
<h:form id="guid_form">
<h:outputText value="#{checkTabAction.guid}" id="server_guid"/>
<p:remoteCommand name="checkGuid" actionListener="#{checkTabAction.checkGuid}" process="@this" partialSubmit="true" />
</h:form>
并添加了一个检查操作,通过比较guid来验证当前浏览器选项卡/窗口:
@ConversationScoped
@Named(value = "checkTabAction")
public class CheckTabAction implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private Logger log;
private String guid = null;
public void checkGuid() {
Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
String guid = params.get("guid").toString();
if (this.guid == null) {
this.guid = guid;
}
if (!StringUtils.equals(this.guid, guid)) {
log.info("New tab detected!");
throw new NonexistentConversationException("New tab detected!");
}
}
public String getGuid() {
return guid;
}
}