【问题标题】:Can I redirect to a valid Wicket page when attempting to access a non-existent page?尝试访问不存在的页面时,我可以重定向到有效的 Wicket 页面吗?
【发布时间】:2012-11-08 18:40:05
【问题描述】:

简介

如果我的 Apache Wicket Web 应用程序(在 GAE/J 上运行)的用户尝试访问不存在的页面,例如:

http://[MyURL]/admin/PageSubscribeX

Web 框架记录以下警告:

org.apache.wicket.core.util.lang.WicketObjects resolveClass: Could not resolve class [[...].admin.PageSubscribeX]
java.lang.ClassNotFoundException: [...].admin.PageSubscribeX
    at com.google.appengine.runtime.Request.process-78915baf06af5f31(Request.java)
    at java.lang.Class.forName(Class.java:133)
    at org.apache.wicket.application.AbstractClassResolver.resolveClass(AbstractClassResolver.java:108)
    at org.apache.wicket.core.util.lang.WicketObjects.resolveClass(WicketObjects.java:71)
    at org.apache.wicket.core.request.mapper.AbstractComponentMapper.getPageClass(AbstractComponentMapper.java:139)
    at org.apache.wicket.core.request.mapper.PackageMapper.parseRequest(PackageMapper.java:148)
    ...
    at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:458)
    at java.lang.Thread.run(Thread.java:679)

GAE/J 以错误 404 页面和文本 Error: NOT_FOUND 响应。

我知道目前使用 GAE/J “当没有为 URL 定义 servlet 映射时,我无法自定义 404 响应页面”。

我的问题

当没有为 URL 定义 servlet 映射时,有什么方法可以为响应指定 Wicket 页面?或者,是否可以定义一些 servlet 映射来将“未找到所有 URL”映射到我选择的 Wicket 页面?

我的软件环境是:

  • 检票口:6.2.0
  • GAE/J:1.7.3
  • Java:1.6.0_37。

一次失败的尝试

按照@biziclop 的cmets,我尝试了以下方法,但失败了。我得到的只是我的错误页面 PageError 每次都显示....

我在WebApplication#init() 中的代码是:

ICompoundRequestMapper crmRoot = getRootRequestMapperAsCompound();
URLNotFoundMapper mapperURLNotFound = new URLNotFoundMapper(null,
 PageError.class);
crmRoot.add(mapperURLNotFound);
setRootRequestMapper(crmRoot);

我的新映射器 URLNotFoundMapper

/**
 * This mapper class is intended to be the mapper of last resort, to be used
 * if all other mappers cannot handle the URL of the current request.
 * <br/>
 * This mapper will cause a defined (error) page to be shown.
 */
public class URLNotFoundMapper extends BookmarkableMapper
{
  private IRequestMapper m_rmRoot = null;
  private Class<? extends IRequestablePage> m_classPage = null;

  /**
   * Constructor.
   * @param rmRoot
   *   The application's previous root request mapper.
   *   If this is <code>null</code> then it is ignored.
   * @param clError
   *   The class of the page which should handle erroneous requests.
   *   This must not be <code>null</code>.
   */
  public URLNotFoundMapper(IRequestMapper rmRoot,
   final Class<? extends IRequestablePage> clError)
  {
    m_rmRoot = rmRoot;
    m_classPage = clError;
  }

  /**
   * Use this mapper as the last option.
   * So let all other mappers try to handle the request first.
   * @param request
   *   The request.
   * @return
   *   The score of the application's previous root request mapper.
   */
  @Override
  public int getCompatibilityScore(Request request)
  {
    return Integer.MIN_VALUE;
  }

  /**
   * This method returns an <code>IRequestHandler</code> for the bookmarkable
   * error page.
   * @param request
   * @return
   *   An <code>IRequestHandler</code> capable of processing a bookmarkable
   *   request.
   *
   */
  @Override
  public IRequestHandler mapRequest(Request request)
  {
    IRequestHandler rhResult = null;
    if (m_rmRoot != null)
      rhResult = m_rmRoot.mapRequest(request);

    if (rhResult != null)
      rhResult = null;    // Another mapper can handle this
    else
    {
      rhResult = processBookmarkable(m_classPage, null);
    }

    return rhResult;
  }

  @Override
  public Url mapHandler(IRequestHandler requestHandler)
  {
    Url urlResult = null;
    if (m_rmRoot != null)
      urlResult = m_rmRoot.mapHandler(requestHandler);

    if (urlResult != null)
      urlResult = null;    // Another mapper can handle this
    else
    {
      PageInfo info = new PageInfo();
      UrlInfo urlInfo = new UrlInfo(new PageComponentInfo(info, null),
       m_classPage, null);
      urlResult = buildUrl(urlInfo);
    }

    return urlResult;
  }

  /**
   * @return
   *   The URL info for the bookmarkable error page.
   */
  @Override
  protected UrlInfo parseRequest(Request request)
  {
    UrlInfo uiResult = null;
    uiResult = new UrlInfo(null, m_classPage, null);
    return uiResult;
  }
}

【问题讨论】:

  • 这当然应该是可能的,查看堆栈跟踪我认为最好在映射器级别处理这个问题。
  • @biziclop 您的意思是修改我的 web.xml 文件以包含“错误页面”元素还是其他内容?
  • 我的意思是编程,因为它已经完成here。在最后的代码 sn-p 中,他们向您展示了如何用自定义实现替换根请求映射器。从那里您可以完全控制您尝试加载哪个页面类以及何时加载。
  • @biziclop 无论如何感谢您,但我尝试使用映射器拦截错误 URL 的尝试失败了。

标签: java google-app-engine wicket http-status-code-404


【解决方案1】:

你需要在你的webapp中配置404 http错误,看看here

提问者摘自以上链接:

<error-page>
  <error-code>404</error-code>
  <location>/[URI portion to point to a customer error page]</location>
</error-page>

【讨论】:

  • 遗憾的是,Google App Engine for Java (GAE/J) 不允许此解决方案使用 web.xml 文件“error-page”元素作为错误代码 404。(实际上,此配置被忽略.) 你或其他人能想到其他解决方案吗?
  • O.o,您可以覆盖 wicket 的错误页面,但这仅适用于服务器内部错误(运行时异常),适用于 404 http 错误据我所知,始终是服务器配置
猜你喜欢
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-16
  • 1970-01-01
相关资源
最近更新 更多