Accueil > professional > Wicket: providing JSON content through Ajax

Wicket: providing JSON content through Ajax

[Article également disponible en Français.]

A few weeks ago, we had a need to give back some JSON content to some client side JavaScript. Not knowing exactly how to do that, we went for a page rendering itself with only the JSON content. Something like that:

 @Override
    protected void onRender(final MarkupStream markupStream)
    {
        try
        {
            OutputStream outputStream = getResponse().getOutputStream();
            outputStream.write(jsonData.getBytes());
            outputStream.flush();
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }

    }

Then, the url for this page was provided to the page through

 
RequestCycle.get().urlFor(jsonPage);

For sure, the call to this page was done through some component encapsulating the whole business.
Yet, while working, this solution had drawbacks. The biggest one, IMHO, being that the extra page means a different context, where the info have to be pushed. It would be nice to be able to stay in the component/context (which is still doable, I agree, but less clean and more work). It’s also quite verbose. On the good side on the picture, this page being filled with less content is then small on the disk when about to be serialized way and forth. You can’t have the cake and eat it 😉

Recently, I was looking for a way to deal with a Wicket Ajax behavior and some jQuery function both acting on the same JavaScript event. And on the way, I found this answer from Richard Wilkinson on a topic named Wicket, Ajax and JSON. And guess what, it’s dead simple to interact between JavaScript and a behavior through JSON data (or whatever content you prefer).
Here is the code from Richard:

 
    AbstractAjaxBehavior behaviour = new AbstractAjaxBehavior()
        {
            private static final long serialVersionUID = 1L;

            @SuppressWarnings("unchecked")
            public void onRequest()
            {
                //get parameters
                final RequestCycle requestCycle = RequestCycle.get();

                final PageParameters pageParameters = new PageParameters(requestCycle.getRequest().getParameterMap());
               
                //do something using nice json library to produce a string of json
                String json = .......
               
               
                requestCycle.setRequestTarget(new StringRequestTarget("application/json", "utf-8", json));
            }

        };
        add(behaviour);

Then, to get at the behavior, one just has to provide the JavaScript with the outcome of

 behaviour.getCallbackUrl(true)

The basic implementation I did and used work all fine, yet I’m not sure yet of all the implications of the boolean provided, whose javadoc is:
* @param onlyTargetActivePage
* if true the callback to this behavior will be ignore if the page is not the last
* one the user accessed

Anyway, in the end, what matters is how easy it is to do ! No more extra page, extra lines and information being passed around. This simple behavior does it all nicely !

Yes, integrating JavaScript and server side is still some work, but damn Wicket provides really first level tools for this!

🙂

++
joseph

PS: Richard speaks as well of JQuery integration for Wicket, formerly wiquery and now integrated into wicketstuff-core as the jquery project. Did anyone ever try it ? Any feedback ?
PS2: More about Richard on his blog Out for a duck, all about Wicket (no new entry since a while though).

Publicités
Étiquettes : , , ,
  1. Peter
    septembre 3, 2010 à 12:55

    Joseph, shouldn’t « data » in requestCycle.setRequestTarget(new StringRequestTarget(« application/json », « utf-8 », data));
    be actually your « json » string?

    Anyway nice post, just working on same wicket/jquery task :p

  2. septembre 3, 2010 à 4:19

    Indeed, typo fixed, thx !

    I’ll comment more later, train to catch right now 🙂

  3. Dmitry
    septembre 9, 2010 à 8:56

    Does this approach allow for live streaming?
    I.e., is it possible to write some … text, then flush, then again some script, then flush in the onRenderMethod?

  4. septembre 10, 2010 à 7:31

    Hi Dmitry

    Why shouldn’t it be usable for streaming ?

    I would just make sure of not having the same page shared by different users, it should work fine. As shown in the 2nd example, one can easily look at the parameters and figure out the proper answer from them.

  1. septembre 3, 2010 à 8:47

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :