24

How can I delete or hide the version number in the URL introduced in Wicket 1.5?

Mounting a page doesn't help.

http://localhost/MyPage/SubPage?0
Stijn Geukens
  • 15,454
  • 8
  • 66
  • 101
rotsch
  • 1,909
  • 16
  • 36

7 Answers7

20

In Application.init():

mount(new MountedMapperWithoutPageComponentInfo("/subpage", MyPage.class));

with the following Mapper class:

public class MountedMapperWithoutPageComponentInfo extends MountedMapper {

  public MountedMapperWithoutPageComponentInfo(String mountPath, Class<? extends IRequestablePage> pageClass) {
    super(mountPath, pageClass, new PageParametersEncoder());
  }

  @Override
  protected void encodePageComponentInfo(Url url, PageComponentInfo info) {
    // do nothing so that component info does not get rendered in url
  }

  @Override 
  public Url mapHandler(IRequestHandler requestHandler) 
  { 
      if (requestHandler instanceof ListenerInterfaceRequestHandler ||
                requestHandler instanceof BookmarkableListenerInterfaceRequestHandler) { 
          return null; 
      } else { 
           return super.mapHandler(requestHandler); 
      } 
  } 
}
Phil McCullick
  • 7,175
  • 2
  • 29
  • 29
Apostolos
  • 10,033
  • 5
  • 24
  • 39
4

The solution using a self-created MountedMapperWithoutPageComponentInfo class doesn't work for Wicket 6.13+, the page won't respond to callback user actions. (Note that there are multiple versions of MountedMapperWithoutPageComponentInfo on the Internet.)

A solution for 6.13+ (tested with 6.15) can be found here:

http://apache-wicket.1842946.n4.nabble.com/Delete-version-number-in-url-td4665752.html

https://svn.apache.org/repos/asf/openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java

// Put this code in your WebApplication subclass
import org.apache.wicket.core.request.mapper.MountedMapper;
import org.apache.wicket.request.component.IRequestablePage;
import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
import org.apache.wicket.request.mapper.info.PageComponentInfo;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.core.request.handler.BookmarkableListenerInterfaceRequestHandler;

private static class NoVersionMapper extends MountedMapper {
    public NoVersionMapper(final Class<? extends IRequestablePage> pageClass) {
        this("/", pageClass);
    }

    public NoVersionMapper(String mountPath, final Class<? extends IRequestablePage> pageClass) {
        super(mountPath, pageClass, new PageParametersEncoder());
    }

    @Override
    protected void encodePageComponentInfo(Url url, PageComponentInfo info) {
        //Does nothing
    }

    @Override
    public Url mapHandler(IRequestHandler requestHandler) {
        if (requestHandler instanceof ListenerInterfaceRequestHandler || requestHandler instanceof BookmarkableListenerInterfaceRequestHandler) {
            return null;
        } else {
            return super.mapHandler(requestHandler);
        }
    }
}

Then you can mount pages using:

// Put this in the init() method of your WebApplication subclass
getRootRequestMapperAsCompound().add(new NoVersionMapper("urlPatternOfAPage", YourPage.class));
Devabc
  • 4,782
  • 5
  • 27
  • 40
4

If you don't want the version number then you page should be completely stateless, the version number is meant for stateful pages. For instance if your page includes a form then you should use the stateless variant of the Form component, that is org.apache.wicket.markup.html.form.StatelessForm. If your page is already completely stateless, you can give wicket a hint by invoking the org.apache.wicket.Page#setStatelessHint method.

Rolf Thunbo
  • 319
  • 1
  • 5
  • 3
    You're right. But I want stateful pages without a version number, this was possible in wicket 1.4. – rotsch Dec 29 '11 at 12:35
3

For me the solution with setStatelessHint didn't work. The following did work:

class MyApplication extends WebApplication {
    @Override protected void init() {
        getRequestCycleSettings().setRenderStrategy(
            IRequestCycleSettings.RenderStrategy.ONE_PASS_RENDER); 
        ....
    }
}
Adrian Smith
  • 17,236
  • 11
  • 71
  • 93
3

Use the following mapper to mount pages, this should work on any book markable page except the homepage.

Here's how to use the mapper in Application.init()

mount(new MountedMapperWithoutPageComponentInfo("/subpage", MyPage.class));

Here's the mapper.

import org.apache.wicket.request.Url;
import org.apache.wicket.request.component.IRequestablePage;
import org.apache.wicket.request.mapper.MountedMapper;
import org.apache.wicket.request.mapper.info.PageComponentInfo;
import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;

public class MountedMapperWithoutPageComponentInfo extends MountedMapper {

  public MountedMapperWithoutPageComponentInfo(String mountPath, Class<? extends IRequestablePage> pageClass) {
    super(mountPath, pageClass, new PageParametersEncoder());
  }

  @Override
  protected void encodePageComponentInfo(Url url, PageComponentInfo info) {
    // does nothing so that component info does not get rendered in url
  }
}
Alinoor
  • 92
  • 1
  • 7
  • I tried the first method, the version number disappears but all the links stops working. The second method doesn't delete the version numbers. – rotsch Dec 28 '11 at 11:01
  • The first method works for me, without any issues. My page has links as well, all work fine. Do you see any errors? Also your correct about the second solution, it doesnt work and I've taken it out, sorry. – Alinoor Dec 28 '11 at 17:21
  • I managed to partially recreate the problem of links not working, in my case there were forms that stopped working.I used the answer from http://stackoverflow.com/questions/2178285/stateless-apache-wicket-stateless-pages-requests to check which of my components were state full, for most of them I just needed to override the getStatelessHint() method to return true,for links and forms I used the stateless version (StatelessLink, StatelessForm). I then stopped using above code and the ComponentInfo wasnt getting rendered anymore and the pages seems to be working from the quicks tests that I did. – Alinoor Dec 29 '11 at 16:17
  • Yes, as mentioned by Rolf Thunbo, the version number is only needed for stateful pages. – rotsch Dec 29 '11 at 17:32
2

For Wicket 8, this NoVersionMapper class works:

https://github.com/apache/openmeetings/blob/master/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java#L314



    public class NoVersionMapper extends MountedMapper {
        public NoVersionMapper(final Class pageClass) {
            this("/", pageClass);
        }

        public NoVersionMapper(String mountPath, final Class pageClass) {
            super(mountPath, pageClass, new PageParametersEncoder());
        }

        @Override
        protected void encodePageComponentInfo(Url url, PageComponentInfo info) {
            //Does nothing
        }

        @Override
        public Url mapHandler(IRequestHandler requestHandler) {
            if (requestHandler instanceof ListenerRequestHandler || requestHandler instanceof BookmarkableListenerRequestHandler) {
                return null;
            } else {
                return super.mapHandler(requestHandler);
            }
        }
    }

This is basically the same as Devabc's code but this one compiles on Wicket 8. It has been tested against known regressions of the previous versions of the code: Ajax works and no page refreshing is triggered when it shouldn't.

  • Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others. Thanks for improving the answer's reference value and making it more understandable! – Tim Diekmann Jun 03 '18 at 13:31
0

The workarounds suggested so far may work with specific releases and have side effects. They should be considered hacks. I have used these hacks and they were broken by new releases. Therefore I have created a request for generic framework support here (please comment / vote): setVersioned(false) should force single Page Version.

Another example of a side effect: Page Reload on Submit of non-versioned Page

user250343
  • 1,163
  • 1
  • 15
  • 24