通过Wicket中的URL提供操作

时间:2013-03-22 14:47:15

标签: wicket wicket-1.6

对于Facebook等服务的身份验证,我们会重定向到Facebook,他们会执行身份验证,然后重定向。一旦他们重定向回来,我们的代码运行会执行某些操作,然后显示响应页面。显示哪个响应页面取决于任何数量的事情。

我们现在正在做的是:

class RedirectTargetPage extends WebPage {
    @Override public void onBeforeRender() {
        String getParam = getRequest().getQueryParameters()
            .getParamterValue("get-param");
        ......
        if (...) setResponsePage(PageOne.class);
        else if (...) setResposnePage(PageTwo.class);
        else ... // etc
    }
}

然后我们使用urlFor(Class<Page>)查找此页面的URL,将其传递给Facebook,Facebook在身份验证后重定向回我们,一切正常。

但是,这不是一个真正的页面吗?我的意思是它只是位于URL后面的一段代码,最后调用setResponsePage。在我看来,我写的东西只是处理请求的东西,似乎我可以创建一个IRequestHandler并使用urlFor(IRequestHandler)获取一个URL,其中包含:

class RedirectTarget implements IRequestHandler {
    @Override public void respond(IRequestCycle requestCycle) {
        String getParam = requestCycle.getRequest().getQueryParameters()
            .getParameterValue("get-param");
        ....
        if (...) requestCycle.setResposnePage(..)
    }
}

唉,urlFor(new RedirectTarget())传递null!出了什么问题?我能做什么?覆盖onBeforeReder有效,但看起来并不优雅......

4 个答案:

答案 0 :(得分:0)

虽然您可以根据您现在用来定义将使用哪个重定向页面的相同条件加载不同的组件来创建RedirectTargetPage页面,但您也应该能够采用IRequesthandler方式。

来自JavaDoc:

  

返回请求处理程序的呈现URL,如果是,则返回null   处理程序无法呈现。

似乎您的处理程序由于某种原因无法呈现。你有没有走过urlFor来看看哪里出错?

答案 1 :(得分:0)

您可以使用自定义请求映射器:

public class FacebookResponseMapper implements IRequestMapper {

  @Override
  public int getCompatibilityScore(Request request) {
    if (getPage(request.getUrl()) != null) {
      return Integer.MAX_VALUE;
    }
    return 0;
  }

  @Override
  public IRequestHandler mapRequest(Request request) {
    Class<? extends Page> page = getPage(request.getUrl());
    if (page != null){
      return new RenderPageRequestHandler(new PageProvider(page));
    }

    return null;
  }

  /**
   * Get a page for the given url.
   */
  protected Class<? extends Page> getPage(Url url) {
    if (!url.getPath().startsWith("from-facebook") {
      return null;
    }

    // detect proper page depending on url parameters
    ...
  }

  @Override
  public Url mapHandler(IRequestHandler requestHandler) {
    return null;
  }
}

在您的申请中注册:

getRootRequestMapperAsCompound().add(new FacebookResponseMapper());

答案 2 :(得分:0)

我遇到了同样的问题,并使用了IRequestHandler的自定义实现。不过,我不确定这是不是一个好主意,因为这些处理程序是按每个实例而不是按类型挂载的。

因此,与页面不同,您可以挂载请求处理程序的单个实例,例如:

mount(new MountMapper("path", CustomHandler.get()));

get()方法检索CustomHandler的单例实例。然后,您可以生成如下链接:

CharSequence relativeUrl = RequestCycle.get().urlFor(CustomHandler.get());
String link = RequestCycle.get().getUrlRenderer().renderFullUrl(Url.parse(relativeUrl));

这对我有用。

但是,我没有看到在生成链接时如何指定查询参数。对于页面,您将使用自己的特定参数映射创建页面的新实例,但由于我们必须使用仅挂载的一个实例,因此这不起作用。

答案 3 :(得分:0)

我可能会误解,但为什么你需要所有额外的非页面内容?

您将与用户做些什么,为什么不将它们直接发送到他们想要去的页面并使用命名参数来指导他们?

示例:

@MountPath(value = "/handlerpage/${fromparam}")
public class MyHandlerPage extends WebPage {
    public MyHandlerPage(PageParameters parameters) {
    super(parameters);
    final StringValue fromParam = parameters.get("fromparam");
        // Do my thing with page depending on the param.
    }
}

这将允许您跳过所有时髦的请求处理程序代码。如果需要,您甚至可以使用选项参数进行设置。