delete version number in url

北战南征 提交于 2019-11-26 17:44:47
Apostolos

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); 
      } 
  } 
}

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.

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));

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
  }
}

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); 
        ....
    }
}

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.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!