ViewExpiredException после аннулирования сессии - PullRequest
0 голосов
/ 11 декабря 2018

Я получил приложение, использующее Primefaces 6.0 / JSF 2.2, в котором у меня есть следующий сценарий.

Пользователь входит в систему, взаимодействуя с bean-компонентом @SessionScoped в приложении, и перенаправляется на homepage.jsf.После этого пользователь переходит на страницу через пункт меню (mypage.jsf).

public void login() throws IOException {

        //.... Authentication mechanism here 

        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext externalContext = context.getExternalContext();
        HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
        externalContext.redirect(new StringBuilder(externalContext.getRequestContextPath())
                                .append("/homepage.jsf").toString());
        return;
}

На той же вкладке он выходит из приложения и автоматически перенаправляется на страницу входа.

public String logout() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    externalContext.invalidateSession();
    return "/login/login.jsf?faces-redirect=true";
}

Примечание : в то время как реализация входа / выхода из системы находится в обработчике @SessionScoped, остальная часть приложения для его действий / перенаправлений - @ ViewScoped.

Пользователь снова входит в приложение и пытается перейти по тому же пункту меню p: на той же странице, в которой он находился (mypage.jsf)

<p:menuitem value="" url="/mypage.jsf?faces-redirect=true" />

. На этом этапе приложение просматривает javax.faces..application.ViewExpiredException: представление не может быть восстановлено.Это поведение описано в многочисленных публикациях в stackoverflow, одна из которых содержит подробную информацию об этом поведении после аннулирования сеанса ( javax.faces.application.ViewExpiredException: представление не может быть восстановлено )

Вещи, которые я пробовал: я знаю, что это не так уж важно, и что в JSF 2.2 по умолчанию установлено значение false, все еще дал ему попытку.

<context-param>
    <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
    <param-value>false</param-value>
</context-param>

Установка количества просмотров вручнуюсессия.Обратите внимание, что только 1 или 2 пользователя работают с приложением, но задайте его на всякий случай.

<context-param>
    <description></description>
    <param-name>com.sun.faces.numberOfViewsInSession</param-name>
    <param-value>15</param-value>
</context-param>
<context-param>
    <description></description>
    <param-name>com.sun.faces.numberOfLogicalViews</param-name>
    <param-value>15</param-value>
</context-param>

Кроме того, я создал фильтр, чтобы избежать кэширования, как упомянуто здесь Запретить пользователю видеть ранеепосещенная защищенная страница после выхода из системы

@WebFilter(servletNames = { "facesServlet" })
public class LoginFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {

            HttpServletRequest req = (HttpServletRequest) request;

            HttpServletResponse res = (HttpServletResponse) response;
            res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP
            res.setHeader("Pragma", "no-cache"); // HTTP 1.0.
            res.setDateHeader("Expires", 0); // Proxies.
            chain.doFilter(request, response);
            return;
    }
}

Я уверен, что установка javax.faces.STATE_SAVING_METHOD на client может решить мою проблему, но эточто-то, чего я стараюсь избегать.

Кроме того, я создал обработчик исключений, чтобы обработать исключение Viewexpireexception и перенаправить пользователя на определенную страницу.Конечно, это просто для разрешения такой ситуации, а не для решения проблемы.

Обновление 1

Я попытался использовать commandLink с ajax, установленным в false, для перенаправления.на «mypage.jsf» на всякий случай, если это была проблема, но с точно таким же исключением

<h:commandLink action="/mypagejsf?faces-redirect=true" ajax="false" value="My Link" />

Обновление 2 После первого выхода из системы и анализа заголовков запросов изСтраница входа, я заметил следующее:

1) Идентификатор сессии в браузере совпадает с идентификатором на сервере

2) Атрибут Referer показывает следующий URL http: //.... / mypage.jsf ?face-redirect = true .Это страница, на которой я получаю исключение, когда пытаюсь получить к нему доступ.

Обновление 3 Я также заметил, что когда я пытаюсь получить доступ к mypage.jsf после второго входа (до возникновения исключения), мой клиент запрашивает (если я не ошибаюсь) стот же идентификатор сеанса, который существует и на сервере.Когда возникает исключение, сеанс на сервере уничтожается и создается новый сеанс.

...