Wicket – forcing page reload on browser back button…

An interesting issue arises when doing AJAX with Wicket, where you have an AJAX-enabled page with a bunch of controls that get generated/refreshed by AJAX. The user then navigates to another page, and subsequently hits the back button and returns the the AJAX page. They click a button and boom! the app explodes, with a “can not find component foo on page bar” error.

The reason this occurs is because most browsers cache the initial version of a page. When the user hits the back button, the browser displays the cached “initial” page. Wicket on the other hand still stores the page state as it was before the user navigated to the subsequent page. When the user clicks a button on the cached page, the component they are clicking on most likely doesn’t exist in the server-side page… hence the boom!

A simple solution to this is to force page reloading on the use of the back button. Add this into a base page class (or pages where you want to force this behaviour):

class MyPage extends WebPage {
   ......
   @Override
   protected void configureResponse() {
       super.configureResponse();
       WebResponse response = getWebRequestCycle().getWebResponse();
       response.setHeader("Cache-Control",
             "no-cache, max-age=0,must-revalidate, no-store");
   }
   .....
}

I’d be interested in other solutions to this problem that aren’t quite so “brute force”. I’m thinking something along the lines of a “DOM ready” javascript hook which causes a synchronisation of the AJAX modified elements of the page on reload. I can see there would be a few issues to iron out with that approach though.

So for now the above looks like a decent workaround.

Related posts:

  1. Getting a non-relative (absolute) URL for a Wicket page
  2. Announcing – visural-wicket
  3. visural-wicket 0.6.5 release is available!
  4. Where Does Wicket Store It’s DiskPageStore Files?
  5. visural-wicket 0.6 released – lots of new components!

This entry was posted in Java, Software Engineering and tagged ajax, Java, tips, web, wicket. Bookmark the permalink.

11 Responses to Wicket – forcing page reload on browser back button…

  1. Timo says:

    Thank you! I’ve had exactly the same issue and spent a hard time figuring out this AJAX stuff and this solution works for me.

  2. PFM says:

    Does this work for you in IE8?

  3. Interesting! Try adding:

    response.setHeader(“Expires”,”-1″);
    response.setHeader(“Pragma”,”no-cache”);

    More info here –
    http://support.microsoft.com/kb/234067

    Seems like IE8 has really aggressive caching. Guess Microsoft wants to improve apparent performance any way they can ;)

  4. Fernando says:

    I am getting the following error.
    Could it be the case you are commenting in this article?

    After adding a picture in a box by ajax, you can click it and goes to the picture’s album. Instead, what happens is the error below. Could this be a case of your article?

    org.apache.wicket.WicketRuntimeException: component holder:moduloAlbumes:module:grid:1:cols:5:imagen:link not found on page com.misdeportes.frontend.entidades.jugadores.paginas.PaginaMiPerfil[id = 3], listener interface = [RequestListenerInterface name=ILinkListener, method=public abstract void org.apache.wicket.markup.html.link.ILinkListener.onLinkClicked()]
    at org.apache.wicket.request.AbstractRequestCycleProcessor.resolveListenerInterfaceTarget(AbstractRequestCycleProcessor.java:416)

  5. It could be, the error you’ve posted is a general one that Wicket gives when the client page state (i.e. the HTML on the client), doesn’t match the server’s page state (i.e. the Wicket component heirarchy).

    This can be caused by the issue I described with browser caching and the back button, but there are a number of other causes as well.

  6. Peter says:

    +9^9 thanks a lot! It worked for me. (I was searching a completely different thing and now I don’t need to search for this bug ;-) )

  7. Julian says:

    Thank you, Thank you, Thank you!

  8. Leo says:

    This worked for us as well. Thanks!

  9. Onur CANCI says:

    Thanks a lot. Simple and effective solution saved me from exploring lots of web site.

  10. Matt Ashley says:

    You are a life saver!!!

  11. Boris says:

    Slightly simpler form also works in recent versions of Wicket (I’m using 1.4.18). Wicket already sets all of these headers except, for some reason, “no-store”.

    @Override
    protected void setHeaders(WebResponse response) {
    super.setHeaders(response);
    response.setHeader(“Cache-Control”, “no-cache, max-age=0, must-revalidate, no-store”);
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>