How can I create a Wicket URL that hides its parameters?

Pops picture Pops · Jun 17, 2011 · Viewed 8.5k times · Source

I'm currently creating a set of links with code like this:

BookmarkablePageLink<CheeseMain> havarti =
    new BookmarkablePageLink<CheeseMain>("havarti", CheeseMain.class);
havarti.setParameter("Title", "Havarti");
havarti.setParameter("Group", "cheeseName");
add(havarti);

The URL that comes out has the format https://mysite.com/;jsessionid=B85EE5CB0349CCA2FE37AF76AB5C30C1?wicket:bookmarkablePage=:com.mycompany.cheese.CheeseMain&Title=Havarti&group=cheeseName.

My problem is that I no longer want the URL for this link to be bookmarkable. Ideally, I would like it to be something simple like https://mysite.com/cheese, but I can live with an ugly URL. The important thing is that the parameters aren't visible.

How should I change the way I'm generating my links? I've looked at the different URL encoding strategies that Wicket provides, but none of them remove the parameters; they just display them differently.

Answer

tetsuo picture tetsuo · Jun 18, 2011

The parameters appear in the URL only if the page is bookmarkable, or the specific link is bookmarkable.

If you create a Link that navigates to the page using setResponsePage(Page) (passing a Page instance) instead of setResponsePage(Class<Page>, PageParameters) (passing a Page class), the link created will not point to the bookmarkable version of the page, but to a stateful instance.

To make this work, though, you must not call the super(PageParameters) constructor (so that the Page doesn't have enough information to build the stateless URL).

In this example, you can navigate to the SecretPage through two different links, one stateless, bookmarkable, and the other stateful.

SecretPage also has two constructors. One receives a PageParameters and calls super passing it. The other receives the value directly via construcor parameter, and doesn't pass it to super (if it'd called super(new PageParameters().add("message",message), as in the commented line, it would automatically redirect to a bookmarkable URL).

HomePage.java:

public class HomePage extends WebPage {
    public HomePage(final PageParameters parameters) {
        add(new BookmarkablePageLink<Void>("bookmarkable", SecretPage.class,
            new PageParameters().add("message", "This message will appear in the URL")));
        add(new Link<Void>("instance") {
            @Override
            public void onClick() {
                setResponsePage(new SecretPage("This message will NOT appear in the URL"));
            }
        });
    }
}

HomePage.html:

<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
<body>
  <p><a wicket:id="bookmarkable">Bookmarkable link (stateless)</a></p>
  <p><a wicket:id="instance">Hidden parameters link (stateful)</a></p>
</body>
</html>

SecretPage.java

public class SecretPage extends WebPage {
    public SecretPage(PageParameters parameters) {
        super(parameters);
        init(parameters.get("message").toString("No message!"));
    }
    public SecretPage(String message) {
        // super(new PageParameters().add("message", message)); // COMMENTED!
        init(message);
    }
    private void init(String message) {
        info(message);
        add(new FeedbackPanel("feedback"));
        add(new BookmarkablePageLink<Void>("back", getApplication().getHomePage()));
    }
}

SecretPage.html

<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
<body>
  <p wicket:id="feedback"></p>
  <p><a wicket:id="back">BACK</a></p>
</body>
</html>

And, to have a simple URL, like http://host/app/secret, you must mount it. You can do it in your WebApplication class.

WicketApplication.java

public class WicketApplication extends WebApplication {
    @Override
    protected void init() {
        super.init();
        mountPage("home", getHomePage());
        mountPage("secret", SecretPage.class);
    }
    public Class<HomePage> getHomePage() {
        return HomePage.class;
    }
}

This example uses Wicket 1.5 (still RC4.2), and need some modifications to work with 1.4.x (some methods and classes were renamed, or moved to different packages), but the idea is the same.