title: Redirect side effects when using browser back button
body: <p>We are using:</p>
  
  <ul>
  <li>JSF 1.2-1.2_07-b03-FCS</li>
  <li>JSTL 1_1-mr2 (special build)</li>
  <li>Java 1.6.0_22-b04</li>
  <li>Eclipse 3.6.0 (Helios)</li>
  <li>Tomcat 6.0.28 (needs to run also on Weblogic)</li>
  <li>IE 7.0.5730.13</li>
  <li>Firefox: 6.0</li>
  </ul>
  
  <p>We have <code>mainForm.jsp</code>, <code>filterForm.jsp</code>, and <code>externalForm.jsp</code> views.</p>
  
  <p>There is a button "Filter" on <code>mainForm.jsp</code> to transition to <code>filterForm.jsp</code>. It does that by a navigation rule:</p>
  
  <pre><code>&lt;h:commandButton value="Filter" action="#{mainBean.filterData}" /&gt;
  </code></pre>
  
  <p>The <code>mainBean.java</code> code is:</p>
  
  <pre><code>public String filterData() {
      doStuff();
      return "filter";
  }
  </code></pre>
  
  <p>This initially transitions correctly to <code>filterForm.jsp</code>. We can go back to the <code>mainForm.jsp</code> with the browser back button. We can do this repeatedly.</p>
  
  <p>On <code>mainForm.jsp</code> we have a table (actually an ILog Gantt Chart, but we don't think that matters), with a "popup" menu on the chart bars. One of the menu options is to redirect to the <code>externalForm.jsp</code>.</p>
  
  <p>Selecting the "redirect" triggers the following method in <code>mainBean.java</code>:</p>
  
  <pre><code>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);
  }
  </code></pre>
  
  <p>This correctly works. The window transitions to <code>externalForm.jsp</code>.</p>
  
  <p>If we press the browser back button on <code>externalForm.jsp</code>, we transition back to <code>mainForm.jsp</code> and things look OK.</p>
  
  <p>If we then press the "Filter" button, the code does not execute the <code>filterData()</code> method, but instead it executes the <code>redirect()</code> method and we transition to the <code>externalForm.jsp</code> view, not the <code>filterForm.jsp</code> view.</p>
  
  <p>Why does it do this and how do we force a call to <code>filterData()</code> instead?</p>
  
  <pre><code>******************************************************************************
  
  BalusC - thank you for your solution.  With a few slight tweeks, it worked great.
  
  The changes I made to web.xml are:
  
      &lt;filter&gt;
         &lt;filter-name&gt;noCacheFilter&lt;/filter-name&gt;
         &lt;filter-class&gt;{my package name}.CacheControlFilter&lt;/filter-class&gt;
      &lt;/filter&gt;
      &lt;filter-mapping&gt;
         &lt;filter-name&gt;noCacheFilter&lt;/filter-name&gt;
         &lt;url-pattern&gt;/faces/*&lt;/url-pattern&gt;
      &lt;/filter-mapping&gt;
  
  
  
  
  Also, I found another solution:
  
  faces-config.xml add:
  
      &lt;lifecycle&gt;
          &lt;phase-listener id="nocache"&gt;{my package name}.
          CacheControlPhaseListener&lt;/phase-listener&gt;
      &lt;/lifecycle&gt;    
  
  
  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
  </code></pre>