Wicket Ajax Timer for Legthy Operations using AjaxSelfUpdatingTimerBehavior

Home / Blog / Java / Wicket Ajax Timer for Legthy Operations using AjaxSelfUpdatingTimerBehavior

Normally, if I have an operation that takes a while to complete in a wicket project, I’ve taken advantage of the LazyLoadingPanel. This works great for simple scenarios, but one major drawback for me is it doesn’t maintain its state across requests. Meaning, if a lazy loading operation is in process, and user decides to refresh the page or hit the back button, that process will be duplicated upon entering the page state again.

A colleague of mine discovered a better approach with the use of the Wicket AjaxSelfUpdatingTimerBehavior. When attached to a component, this behavior will cause the component to refresh continually (or until “stop()” is called), allowing the developer to implement lengthy operations within a new thread, which will be monitored by the onBeforeRender() method of the component. Lets take a look at how this is implemented:

For an example, lets say we have a process called ProcessOrder that invokes a few services which may cause it to be lengthy. We can create an “ajaxy” spinner to display while the ProcessOrder is executing, and then once the operation is complete, a session flag will be set, and the panel will update its view.


public class OrderPanel extends Panel{

     private WebMarkupContainer ajaxSpinner;
     private WebMarkupContainer orderConfirmation;
     private AjaxSelfUpdatingTimerBehavior updateBehavior;

     public OrderPanel(String id){
          super(id);

          add(ajaxSpinner = new WebMarkupContainer("ajaxSpinner"));
          add(orderConfirmation= new WebMarkupContainer("orderConfirmation"));
          orderConfirmation.setVisible(false);

          add(updateBehavior = new AjaxSelfUpdatingTimerBehavior(Duration
                .seconds(5));

          new OrderProcessThread(getSession()).start();
     }

     @Override
     protected void onBeforeRender() {
        super.onBeforeRender();

          if(((MySession)getSession()).isOrderProcessComplete(true)){
               // This means our worker thread has finished and updated the session.
               // Now, we can update our view states to show the order confirmation.
               ajaxSpinner.setVisible(false);
               orderConfirmation.setVisible(true);

               // don't forget to stop the update behavior
               updateBehavior.stop();
          }
     }

     private class OrderProcessThread extends Thread{
     
          private MySession session;

          public OrderProcessThread(Session session){
               this.session = (MySession) session;
          }

          @Override
          public void run() {
                try{
                // for the sake of this example, imagine this method will
                // invoke some service that will take a while to finish
                }catch(Exception e){
                }finally{
                     session.setIsOrderProcessComplete(true);
                }
          }
     }
}

The code above should be fairly straight forward, but I can expand on this if anyone would like more examples for further explanations. In a nutshell, the panel has two markup containers. One to show while our thread processes the order, and another to show some kind of confirmation message. Upon initialization, the spinner markup container is displayed and the confirmation markup container is set to be invisible. We then add the ajax updating behavior, which will cause a round trip “refresh” every 5 seconds (this is set within its initialization). The last thing we do is start our thread.

When the page is rendered, the ajax container will be displayed, and after 5 seconds, our Panel’s onBeforeRender() will again be invoked caused by the ajax request. Here, we can check if the thread has set the “IsOrderProcessComplete” flag, and if so, we can update our visual elements.

Keep in mind that the code above was written from memory for example purposes, and it is not intended to be production worthy. This is just the basic approach used to get the ajax timer implemented. As you can see, Wicket does a great job of making it easy for us developers to implement snazzy ajax applications with little code.

Comments
  • tsanko

    Wonderful ..thanks a lot for posting a good informitive blog

Leave a Comment