Перенаправление побочных эффектов при использовании кнопки браузера назад - PullRequest
4 голосов
/ 18 ноября 2011

Мы используем:

  • JSF 1.2-1.2_07-b03-FCS
  • JSTL 1_1-mr2 (специальная сборка)
  • Java 1.6.0_22-b04
  • Eclipse 3.6.0 (Helios)
  • Tomcat 6.0.28 (необходимо также запустить на Weblogic)
  • IE 7.0.5730.13
  • Firefox:6.0

У нас есть mainForm.jsp, filterForm.jsp и externalForm.jsp просмотров.

На mainForm.jsp есть кнопка «Фильтр» для перехода к filterForm.jsp.Это выполняется по правилу навигации:

<h:commandButton value="Filter" action="#{mainBean.filterData}" />

Код mainBean.java:

public String filterData() {
    doStuff();
    return "filter";
}

Первоначально он корректно переходит на filterForm.jsp.Мы можем вернуться к mainForm.jsp с помощью кнопки возврата браузера.Мы можем делать это многократно.

На mainForm.jsp у нас есть таблица (фактически диаграмма ILog Gantt, но мы не думаем, что это имеет значение) с всплывающим меню на столбцах диаграммы.Один из пунктов меню - перенаправление на externalForm.jsp.

. При выборе «перенаправление» в mainBean.java запускается следующий метод:

public void redirect(FacesMenuActionEvent event) {
    if (svr == null) {
        svr = new SetupURL(); // Simple code to set up the full URL
    }

    redirectUrl = svr.redirect(event);  // URL of externalForm.jsp
    svr.redirectData(redirectUrl);
}

Это работает правильно.Окно перейдет к externalForm.jsp.

Если мы нажмем кнопку браузера назад на externalForm.jsp, мы вернемся к mainForm.jsp и все будет в порядке.

Если мы затем нажмем "Кнопка «Фильтр», код не выполняет метод filterData(), но вместо этого он выполняет метод redirect(), и мы переходим к представлению externalForm.jsp, а не к представлению filterForm.jsp.

Почему это происходит?сделать это, и как мы можем вместо этого вызвать filterData()?

******************************************************************************

BalusC - thank you for your solution.  With a few slight tweeks, it worked great.

The changes I made to web.xml are:

    <filter>
       <filter-name>noCacheFilter</filter-name>
       <filter-class>{my package name}.CacheControlFilter</filter-class>
    </filter>
    <filter-mapping>
       <filter-name>noCacheFilter</filter-name>
       <url-pattern>/faces/*</url-pattern>
    </filter-mapping>




Also, I found another solution:

faces-config.xml add:

    <lifecycle>
        <phase-listener id="nocache">{my package name}.
        CacheControlPhaseListener</phase-listener>
    </lifecycle>    


Create file CacheControlPhaseListener.java:

package {my package name};

import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.servlet.http.HttpServletResponse;

public class CacheControlPhaseListener implements PhaseListener {

    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }

    public void afterPhase(PhaseEvent event) {
    }

    public void beforePhase(PhaseEvent event) {
        FacesContext facesContext = event.getFacesContext();
        HttpServletResponse response = (HttpServletResponse) facesContext
                .getExternalContext().getResponse();
        response.addHeader("Pragma", "no-cache");
        response.addHeader("Cache-Control", "no-cache");
        // Stronger according to blog comment below that references HTTP spec
        response.addHeader("Cache-Control", "no-store");
        response.addHeader("Cache-Control", "must-revalidate");
        // some date in the past
        response.addHeader("Expires", "Mon, 8 Aug 2006 10:00:00 GMT");
    }
}

Both seem to work.



Thanks,
John

1 Ответ

10 голосов
/ 18 ноября 2011

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

Лучшее решение - дать браузеру указание не кэшировать динамические страницы JSF, а каждый раз запрашивать его прямо с сервера. Вы можете сделать это с помощью Filter, который имеет следующие строки в методе doFilter():

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
    HttpServletResponse res = (HttpServletResponse) response;
    res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
    res.setHeader("Pragma", "no-cache"); // HTTP 1.0.
    res.setDateHeader("Expires", 0); // Proxies.
    chain.doFilter(request, response);
}

Отобразите это на том же <servlet-name> из FacesServlet в web.xml. Э.Г.

<filter>
   <filter-name>noCacheFilter</filter-name>
   <filter-class>com.example.NoCacheFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>noCacheFilter</filter-name>
   <servlet-name>facesServlet</servlet-name>
</filter-mapping>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...