Сохранение сеанса в течение неопределенного времени

Есть ли способ сохранить активность сеанса страницы, не прибегая к отправке состояния клиенту? Я не могу установить STATE_SAVING_METHOD в client, и я бы предпочел не использовать a4j:keepalive.

Я попытался использовать простой скрытый iframe, который отправляет рассматриваемый Bean, но делает недействительной главную страницу.

Я использую JSF 1.2 и myfaces.

Это делается для того, чтобы обойти ViewExpiredException на странице, которая не требует от пользователя входа в систему. Большинство существующих сайтов требуют, чтобы пользователь вошел в систему.


person OddProblems    schedule 09.01.2012    source источник
comment
Не могли бы вы объяснить вариант использования?   -  person Adrian Mitev    schedule 09.01.2012
comment
@AdrianMitev Конечно, я добавил несколько дополнительных комментариев. Исключение ViewExpiredException срабатывает примерно через 10 минут. Я не могу изменить время ожидания.   -  person OddProblems    schedule 09.01.2012


Ответы (2)


Реализуйте опрос ajax как «пульс», чтобы поддерживать сеанс в рабочем состоянии. В простейшем случае вы можете добиться этого следующим образом с помощью небольшого jQuery, чтобы избежать стандартного кода из 100 строк, чтобы заставить его работать. во всех разных браузерах, о которых мир знает:

<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
    $(document).ready(function() {
        setInterval(function() {
            $.get("${pageContext.request.contextPath}/poll");
        }, ${(pageContext.session.maxInactiveInterval - 10) * 1000});
    });
</script>

Печать ${pageContext.session.maxInactiveInterval} оставшиеся секунды сеансу еще предстоит жить в соответствии с конфигурацией на стороне сервера (которая, кстати, контролируется <session-timeout> в web.xml) и вычитается с 10 секундами, просто чтобы успеть до того, как он автоматически истечет, и конвертируется в миллисекунды, поэтому что он соответствует ожиданиям setInterval().

$.get() отправляет запрос ajax GET по указанному URL-адресу. В приведенном выше примере вам нужно сопоставить сервлет с шаблоном URL /poll и сделать в основном следующее в методе doGet():

request.getSession(); // Keep session alive.

Это должно быть так.

person BalusC    schedule 09.01.2012
comment
Эта стратегия великолепна и позволяет сократить время ожидания сеанса в web.xml до 1 минуты и сохранить требование иметь высокое значение времени ожидания сеанса. Проблема увеличения тайм-аута сеанса в web.xml заключается в том, что даже неиспользуемые логические представления с областью просмотра будут храниться в течение заданного тайм-аута, если вы выполняете прямую навигацию GET (в отличие от навигации JSF). - person Yamada; 28.08.2015

Ответ BalusC помог мне выполнить это требование в моем приложении, но, поскольку я использую PrimeFaces, я хотел поделиться тем, как BalusC ответ вдохновил код, который я использую для этого.

xhtml-страница

<p:poll listener="#{pf_usersController.keepUserSessionAlive()}"
        interval="#{session.maxInactiveInterval - 10}" />

фасоль

public void keepUserSessionAlive() {
    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
    request.getSession();
}

как всегда, спасибо, BalusC!

РЕДАКТИРОВАТЬ: Конечный пользователь проверил это сегодня утром, и он отлично работает! мое приложение обычно вызывает тайм-аут сеанса через 15 минут после полного обновления страницы (перенаправление на sessionExpired.xhtml через метаобновление на основе значения session.maxInactiveInterval и тайм-аута сеанса в web.xml); если пользователь находится на одной странице, выполняя кучу запросов AJAX, время ожидания сеанса истекает, поскольку AJAX != полное обновление страницы, но этот код позволял конечному пользователю «поддерживать сеанс в рабочем состоянии», пока конечный пользователь находился на странице платежной ведомости в приложении, и сеанс оставался активным на 1-2 часа! :)

person Howard    schedule 21.10.2013
comment
Я не рекомендую этот трюк. Если вы участвуете в беседе, есть вероятность, что вы получите исключение javax.enterprise.context.BusyConversationException. Например, пользователь нажимает кнопку. Тем временем опросчик активизируется, но, учитывая, что запросы диалогов сериализуются, запрос опросера может истечь по тайм-ауту (BusyConversationException), если предыдущий запрос занимает более одной секунды. Проблема в том, что запрос опроса не должен находиться внутри разговора. Решение BalusC позволяет полностью избежать этой проблемы. - person agori; 27.10.2015
comment
@агори, спасибо. В моем случае pf_usersController — это CDI SessionScoped, и я не использую bean-компоненты с областью диалога. - person Howard; 28.10.2015