Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I mimic HybridUrlCodingStrategy in Wicket 1.5?

Tags:

java

wicket

We have an existing Java Wicket 1.4 application which uses the HybridUrlCodingStrategy extensively:

mount(new HybridUrlCodingStrategy("/myurl", MyPage.class));

This results in our URL's looking like:

http://host/myurl/paramName1/paramValue1/paramName2/paramValue2

I would like to maintain this URL format in Wicket 1.5, however the HybridUrlCodingStrategy has been removed. In wicket 1.5, pages are mounted as:

mountPage("/myurl", MyPage.class);

Which results in traditional URLs like:

http://host/myurl?paramName1=paramValue2&paramName2=paramValue2

I have read that we should be using the MountedMapper class, but looking at the Wicket 1.5 examples, API docs, and source code, it is still not clear to me how to get the same behavior with MountedMapper as we are getting with the HybridUrlCodingStrategy.

Does anyone know how to do this?

like image 900
ThePizzle Avatar asked May 27 '11 15:05

ThePizzle


3 Answers

Maybe something like this:

mountPage("/myurl/paramName1/${paramValue1}/paramName2/${paramValue2}", MyPage.class)

would work? Granted, you'd have to manually specify your parameters, which could be a lot more work. The MountedMapper class javadoc explains how to use parameters.

The other option I can think of would be (Note: this is untested):

class MyPageParametersEncoder implements IPageParametersEncoder() {
    public PageParameters decodePageParameters(Request request)
    {
        PageParameters parameters = new PageParameters();

        int i = 0;
        for (Iterator<String> segment = request.getUrl().getSegements().iterator(); segment.hasNext()) {
            String key = segment.next();
            String value = segment.next();

            parameters.add(key, value);
        }

        return parameters.isEmpty() ? null : parameters;
    }

    public Url encodePageParameters(PageParameters pageParameters)
    {
        Url url = new Url();

        for (PageParemeters.NamedPair pair : pageParameters.getAllNamed() {
            url.getSegments().add(pair.getKey());
            url.getSegments().add(pair.getValue());
        }

        return url;
    }
}

mount(new MountedMapper("/myurl/", MyPage.class, new MyPageParametersEncoder());
like image 131
luniv Avatar answered Oct 24 '22 11:10

luniv


No need of custom IPageParametersEncoder.

With mountPage("/myurl/paramName1/${paramValue1}/paramName2/${paramValue2}", MyPage.class) the URL will look like in 1.4 but the values will be reachable as StringValue value1 = parameters.get("paramValue1"). Similar for value2.

With mountPage("/myurl/${paramValue1}/${paramValue2}", MyPage.class) is the same according to extracting the values, just shorter URL will be used.

It also supports optional paramaters - #{optionalValue3}.

like image 31
martin-g Avatar answered Oct 24 '22 10:10

martin-g


NOTE: A new class has been added to Wicket 1.5.2 for backwards compatibility with 1.4 style URL encoding. It's called UrlPathPageParametersEncoder - use that if you're migrating a wicket 1.4 app to 1.5 and you have bookmarkable page links of the style:

www.mysite.com/name1/value1/name2/value2

We had the exact same issue when migrating from 1.4 to 1.5. Any 1.4 app that has been live for a while would likely have a collection of links pointing to it from external sites on the web. You really want the Wicket 1.5 version of your app to be able to handle these existing hybrid links without generating an error.

When migrating to 1.5, without a 1.4 compatible IPageParametersEncoder implementation, you need to include the full parameter specification in every mount if you want to avoid making changes to each individual Page class that reads parameters. The implementation below means that is no longer necessary. Just mount the page as livid suggests above.

I'm submitting this .java file as a patch to the Wicket devs - they may include it in Wicket in the future to make it easy to implement backwards compatible URL parameter encoding for other 1.4 migrators.

I took luniv's sample code above and made a few small changes to get it compiling/working. The following should work as a parameter encoder to provide 1.4.x style parameter encoding in 1.5.

    package org.apache.wicket.request.mapper.parameter;

    import java.lang.*;

    import org.apache.wicket.request.mapper.parameter.IPageParametersEncoder;

    import java.util.Iterator;

    import org.apache.wicket.request.Request;

    import org.apache.wicket.request.Url;

    import org.apache.wicket.request.mapper.parameter.PageParameters;

    public 
    class HybridPageParametersEncoder implements IPageParametersEncoder
    {
    /**
     * Encodes a URL in the form:
     * 
     * /mountpoint/paramName1/paramValue1/paramName2/paramValue2 
     * 
     * (i.e. a URL using the pre wicket 1.5 Hybrid URL strategy)
     */
    public Url encodePageParameters(PageParameters pageParameters)
    {
        Url url = new Url();

        for (PageParameters.NamedPair pair : pageParameters.getAllNamed())
        {
            url.getSegments().add(pair.getKey());
            url.getSegments().add(pair.getValue());
        }

        return url;
    }

    /**
     * Decodes a URL in the form:
     * 
     * /mountpoint/paramName1/paramValue1/paramName2/paramValue2 
     * 
     * (i.e. a URL using the pre wicket 1.5 Hybrid URL strategy)
     */
    public PageParameters decodePageParameters(Request request)
    {
        PageParameters parameters = new PageParameters();

        int i = 0;
        for (Iterator<String> segment = request.getUrl().getSegments().iterator(); segment.hasNext(); )
        {
            String key = segment.next();
            String value = segment.next();

            parameters.add(key, value);
        }

        return parameters.isEmpty() ? null : parameters;
    }
}
like image 37
Volksman Avatar answered Oct 24 '22 10:10

Volksman