介绍
如果我的 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 page 和 text 响应Error: NOT_FOUND
。
我知道目前使用 GAE/JI “当没有为 URL 定义 servlet 映射时,无法自定义 404 响应页面”。
我的问题
当没有为 URL 定义 servlet 映射时,有什么方法可以为响应指定 Wicket 页面?或者,是否可以定义一些 servlet 映射来将“所有未找到的 URL”映射到我选择的 Wicket 页面?
我的软件环境是:
- 检票口:6.2.0
- GAE/J:1.7.3
- 爪哇:1.6.0_37。
一次失败的尝试
根据@biziclop 的评论,我尝试了以下方法,但失败了。我得到的只是我的错误页面 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;
}
}