перенаправление лиц и кнопка возврата приводят к некорректной работе других ссылок - PullRequest
6 голосов
/ 20 октября 2011

У меня есть вопрос, окружающий лица навигации.

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

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

На обеих страницах есть bean-объекты с областью видимости.

Это все работает замечательно для ПЕРВОЙ ссылки, которая нажата. Первая страница перенаправляет на новый URL-адрес, и дело загружается, как ожидается.

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

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

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

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

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

Спасибо!

1 Ответ

12 голосов
/ 20 октября 2011

По сути, вы должны указать браузеру не кэшировать динамически генерируемые страницы 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-запрос, который должен воссоздать состояние просмотра и привести к странице сформа с правильным значением состояния скрытого поля.

...