Альтернатива многооконной обработке Deltaspike в приложении Seam 3

У меня проблемы с многооконным управлением в моем приложении. В настоящее время я использую Conversation Scope для включения работы с несколькими окнами / вкладками, но в случае, если пользователь открывает ссылку (кнопку) на новой вкладке, диалог разделяется между старой и новой вкладками.

У Apache Deltaspike есть решение для этого (http://deltaspike.apache.org/documentation/#_module_overview), но я уже использую Seam 3 (и JSF 2.1) и не хочу переходить на Deltaspike.

Итак, я ищу альтернативное решение без Deltaspike или можно ли использовать Deltaspike И Seam 3?


person user1127860    schedule 02.12.2014    source источник
comment
Если можете, обновитесь до JSF-2.2: теперь он обрабатывает несколько окон.   -  person kolossus    schedule 02.12.2014
comment
В конце концов, я читал об этом в JSF 2.2, это то, что не работает, если пользователь открывает ссылку / кнопку в новой вкладке, потому что идентификатор окна будет одинаковым на обеих вкладках. В любом случае обновление до JSF 2.2 в настоящее время невозможно.   -  person user1127860    schedule 04.12.2014
comment
JSF 2.2 просто предоставляет ClientWindow, но не управляет его областью. Используйте DeltaSpike вместо Seam3. DeltaSpike - это будущее на этом пути, и оно просто потрясающее!   -  person Dar Whi    schedule 06.12.2014


Ответы (1)


Я создаю решение с помощью p: remoteCommand и этого ответа: В javascript, как я могу однозначно отличить одно окно браузера от другого, которые находятся под одним и тем же идентификатором сеанса на основе cookie

Я добавил этот JS в свой шаблон, который создает уникальный идентификатор для каждой вкладки браузера и сохраняет его в 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;
    }

}
person user1127860    schedule 08.12.2014