Face-redirect и кнопка "назад" заставляют другие ссылки работать неправильно

У меня вопрос, связанный с навигацией лиц.

Итак, у меня есть страница, которая принимает параметр запроса для загрузки определенного пользователя. На этой странице отображается список commandLink, который при нажатии перенаправляется на другую страницу с использованием неявной навигации. Пользователь загружается путем вызова метода в "preRenderView".

Страница, на которую мы перенаправляем, также принимает параметр запроса, чтобы определить, какой случай загрузить. На странице также используется preRenderView.

Обе страницы имеют beans, которые имеют область видимости.

Все это работает отлично для ссылки FIRST, которая нажата. Первая страница перенаправляет на новый URL-адрес, и корпус загружается, как ожидалось.

ОДНАКО, если я нажму кнопку браузера назад, а затем нажмите другую ссылку, страница НЕ перенаправляется. Он освежает (вместо этого) и, очевидно, не занимается делами.

После обновления я могу щелкнуть ссылку и перенаправить ее правильно.

Теперь все это отлично работает, когда первая страница bean хранится в сеансе, но я не хочу злоупотреблять состоянием сеанса, и я не думаю, что мне должно быть необходимо, чтобы я сохранил эти данные в сеансе.

Я знаю, что могу исправить это, если страница автоматически перезагрузится, когда я нажму кнопку "Назад" (потому что представление будет воссоздано), но я не уверен, что это правильное решение. (и я не уверен, как я это сделал бы)

Есть ли у кого-нибудь предложения? Это похоже на довольно распространенный случай использования, но я не мог найти примеров.

Спасибо!

Ответ 1

В принципе, вам нужно сообщить браузеру, чтобы он не кэшировал динамически созданные JSF-страницы, имея при этом метод сохранения состояния представления, установленный (по умолчанию) server. Состояние представления отслеживается полем <input type="hidden" name="javax.faces.ViewState"> в форме сгенерированной страницы JSF с идентификатором состояния представления в качестве входного значения. Когда вы отправляете страницу и переходите на другую страницу, состояние просмотра прерывается на стороне сервера и больше не существует. Получение страницы из кеша браузера все равно даст вам этот старый идентификатор состояния представления как значение скрытого ввода. Отправка этой формы не будет работать вообще, поскольку состояние просмотра на стороне сервера не может быть найдено.

Вы хотите получить новую новую страницу прямо с сервера, а не из кеша браузера. Чтобы сообщить браузеру об этом, создайте Filter следующим образом:

@WebFilter(servletNames={"Faces Servlet"})
public class NoCacheFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpReq = (HttpServletRequest) request;
        HttpServletResponse httpRes = (HttpServletResponse) response;

        if (!httpReq.getRequestURI().startsWith(httpReq.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
            httpRes.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
            httpRes.setHeader("Pragma", "no-cache"); // HTTP 1.0.
            httpRes.setDateHeader("Expires", 0); // Proxies.
        }

        chain.doFilter(request, response);
    }

    // ...
}

Таким образом, кнопка "Назад" отправит полноправный HTTP-запрос, который должен воссоздать состояние представления и привести к странице с формой с соответствующим скрытым значением поля вида.