今天抽出了点时间来查看T4的源代码,就为了解决StaleLinkException StaleSessionException 这个问题,这个问题T4回返回一些英文的提示信息这对使用系统的人来说是很不友好的提示。
查看T4的源代码发现 处理这个exception的代码在 AbstractEngine 这个类里面代码如下
[code]
public void service(WebRequest request, WebResponse response) throws IOException
{
IRequestCycle cycle = null;
IMonitor monitor = null;
IEngineService service = null;
if (_infrastructure == null){
_infrastructure = (Infrastructure) request.getAttribute(Constants.INFRASTRUCTURE_KEY);
}
// Create the request cycle; if this fails, there's not much that can be done ... everything
// else in Tapestry relies on the RequestCycle.
try
{
cycle = _infrastructure.getRequestCycleFactory().newRequestCycle(this);
}
catch (RuntimeException ex)
{
throw ex;
}
catch (Exception ex)
{
throw new IOException(ex.getMessage());
}
try
{
try
{
monitor = cycle.getMonitor();
service = cycle.getService();
monitor.serviceBegin(service.getName(), _infrastructure.getRequest()
.getRequestURI());
// Let the service handle the rest of the request.
service.service(cycle);
return;
}
catch (PageRedirectException ex)
{
handlePageRedirectException(cycle, ex);
}
catch (RedirectException ex)
{
handleRedirectException(cycle, ex);
}
catch (StaleLinkException ex)
{
handleStaleLinkException(cycle, ex);
}
catch (StaleSessionException ex)
{
handleStaleSessionException(cycle, ex);
}
}
catch (Exception ex)
{
monitor.serviceException(ex);
// Attempt to switch to the exception page. However, this may itself
// fail for a number of reasons, in which case an ApplicationRuntimeException is
// thrown.
if (LOG.isDebugEnabled())
LOG.debug("Uncaught exception", ex);
activateExceptionPage(cycle, ex);
}
finally
{
if (service != null){
monitor.serviceEnd(service.getName());
}
try
{
cycle.cleanup();
_infrastructure.getApplicationStateManager().flush();
}
catch (Exception ex)
{System.out.println("%%%-"+"AbstractEngine"+"_20");
reportException(EngineMessages.exceptionDuringCleanup(ex), ex);
}
}
}
[/code]
可以看到 处理 exception 就是
handleRedirectException(cycle, ex), handleStaleLinkException(cycle, ex);
这两个方法
这两个方法如下:
[code]
protected void handleStaleLinkException(IRequestCycle cycle, StaleLinkException exception)
throws IOException
{
_infrastructure.getStaleLinkExceptionPresenter()
.presentStaleLinkException(cycle, exception);
}
protected void handleStaleSessionException(IRequestCycle cycle, StaleSessionException exception)
throws IOException
{
_infrastructure.getStaleSessionExceptionPresenter().presentStaleSessionException(
cycle,
exception);
}
[/code]
继续 跟踪方法的执行 :
[code]
public StaleSessionExceptionPresenter getStaleSessionExceptionPresenter()
{
return (StaleSessionExceptionPresenter) getProperty("staleSessionExceptionPresenter");
}
public StaleLinkExceptionPresenter getStaleLinkExceptionPresenter()
{
return (StaleLinkExceptionPresenter) getProperty("staleLinkExceptionPresenter");
}
public class StaleSessionExceptionPresenterImpl implements StaleSessionExceptionPresenter
{
private ResponseRenderer _responseRenderer;
private String _pageName;
public void presentStaleSessionException(IRequestCycle cycle, StaleSessionException cause)
throws IOException
{
IPage exceptionPage = cycle.getPage(_pageName);
cycle.activate(exceptionPage);
_responseRenderer.renderResponse(cycle);
}
public void setPageName(String pageName)
{
_pageName = pageName;
}
public void setResponseRenderer(ResponseRenderer responseRenderer)
{
_responseRenderer = responseRenderer;
}
}
public class StaleLinkExceptionPresenterImpl implements StaleLinkExceptionPresenter
{
private ResponseRenderer _responseRenderer;
private String _pageName;
public void presentStaleLinkException(IRequestCycle cycle, StaleLinkException cause)
throws IOException
{
IPage exceptionPage = cycle.getPage(_pageName);
PropertyUtils.write(exceptionPage, "message", cause.getMessage());
cycle.activate(exceptionPage);
_responseRenderer.renderResponse(cycle);
}
public void setPageName(String pageName)
{
_pageName = pageName;
}
public void setResponseRenderer(ResponseRenderer responseRenderer)
{
_responseRenderer = responseRenderer;
}
}
[/code]
继续跟踪到上面的方法后可以发现_pageName 的名字:StaleLink,StaleSession
经过查看知道这个名字是从 Framework.library 文件里提取的,打开这个文件可以找到
下面的三句话
[code]
<page name="StaleLink" specification-path="pages/StaleLink.page"/>
<page name="StaleSession" specification-path="pages/StaleSession.page"/>
<page name="Exception" specification-path="pages/Exception.page"/>
[/code]
将上面的代码修改为
[code]
<page name="StaleLink" specification-path="pub/ErrorPage"/>
<page name="StaleSession" specification-path="pub/ErrorPage"/>
<page name="Exception" specification-path="pages/Exception.page"/>
[/code]
搞定,这里说明一下exception 可以通过下面的代码配置,但用同样的配置思想配置其他
两个exception就不行,无奈之下只好修改他的源文件
[code]
<contribution configuration-id="tapestry.InfrastructureOverrides">
<property name="exceptionPageName" value="pub/ErrorPage"/>
</contribution>
[/code]
在网上搜索一下--发现有了更简便的方法来处理这个问题---
自你的application配置文件中加上下面的代码 T4会自动替换自己的基础组建
但注意timeout的类需要继承StaleLink类
[code]
<page name="StaleLink" specification-path="/pub/TimeOut.page"/>
<page name="StaleSession" specification-path="/pub/TimeOut.page"/>[/code]
参考文档:
http://www.blogjava.net/tapestry/archive/2007/01/29/96568.aspx
查看T4的源代码发现 处理这个exception的代码在 AbstractEngine 这个类里面代码如下
[code]
public void service(WebRequest request, WebResponse response) throws IOException
{
IRequestCycle cycle = null;
IMonitor monitor = null;
IEngineService service = null;
if (_infrastructure == null){
_infrastructure = (Infrastructure) request.getAttribute(Constants.INFRASTRUCTURE_KEY);
}
// Create the request cycle; if this fails, there's not much that can be done ... everything
// else in Tapestry relies on the RequestCycle.
try
{
cycle = _infrastructure.getRequestCycleFactory().newRequestCycle(this);
}
catch (RuntimeException ex)
{
throw ex;
}
catch (Exception ex)
{
throw new IOException(ex.getMessage());
}
try
{
try
{
monitor = cycle.getMonitor();
service = cycle.getService();
monitor.serviceBegin(service.getName(), _infrastructure.getRequest()
.getRequestURI());
// Let the service handle the rest of the request.
service.service(cycle);
return;
}
catch (PageRedirectException ex)
{
handlePageRedirectException(cycle, ex);
}
catch (RedirectException ex)
{
handleRedirectException(cycle, ex);
}
catch (StaleLinkException ex)
{
handleStaleLinkException(cycle, ex);
}
catch (StaleSessionException ex)
{
handleStaleSessionException(cycle, ex);
}
}
catch (Exception ex)
{
monitor.serviceException(ex);
// Attempt to switch to the exception page. However, this may itself
// fail for a number of reasons, in which case an ApplicationRuntimeException is
// thrown.
if (LOG.isDebugEnabled())
LOG.debug("Uncaught exception", ex);
activateExceptionPage(cycle, ex);
}
finally
{
if (service != null){
monitor.serviceEnd(service.getName());
}
try
{
cycle.cleanup();
_infrastructure.getApplicationStateManager().flush();
}
catch (Exception ex)
{System.out.println("%%%-"+"AbstractEngine"+"_20");
reportException(EngineMessages.exceptionDuringCleanup(ex), ex);
}
}
}
[/code]
可以看到 处理 exception 就是
handleRedirectException(cycle, ex), handleStaleLinkException(cycle, ex);
这两个方法
这两个方法如下:
[code]
protected void handleStaleLinkException(IRequestCycle cycle, StaleLinkException exception)
throws IOException
{
_infrastructure.getStaleLinkExceptionPresenter()
.presentStaleLinkException(cycle, exception);
}
protected void handleStaleSessionException(IRequestCycle cycle, StaleSessionException exception)
throws IOException
{
_infrastructure.getStaleSessionExceptionPresenter().presentStaleSessionException(
cycle,
exception);
}
[/code]
继续 跟踪方法的执行 :
[code]
public StaleSessionExceptionPresenter getStaleSessionExceptionPresenter()
{
return (StaleSessionExceptionPresenter) getProperty("staleSessionExceptionPresenter");
}
public StaleLinkExceptionPresenter getStaleLinkExceptionPresenter()
{
return (StaleLinkExceptionPresenter) getProperty("staleLinkExceptionPresenter");
}
public class StaleSessionExceptionPresenterImpl implements StaleSessionExceptionPresenter
{
private ResponseRenderer _responseRenderer;
private String _pageName;
public void presentStaleSessionException(IRequestCycle cycle, StaleSessionException cause)
throws IOException
{
IPage exceptionPage = cycle.getPage(_pageName);
cycle.activate(exceptionPage);
_responseRenderer.renderResponse(cycle);
}
public void setPageName(String pageName)
{
_pageName = pageName;
}
public void setResponseRenderer(ResponseRenderer responseRenderer)
{
_responseRenderer = responseRenderer;
}
}
public class StaleLinkExceptionPresenterImpl implements StaleLinkExceptionPresenter
{
private ResponseRenderer _responseRenderer;
private String _pageName;
public void presentStaleLinkException(IRequestCycle cycle, StaleLinkException cause)
throws IOException
{
IPage exceptionPage = cycle.getPage(_pageName);
PropertyUtils.write(exceptionPage, "message", cause.getMessage());
cycle.activate(exceptionPage);
_responseRenderer.renderResponse(cycle);
}
public void setPageName(String pageName)
{
_pageName = pageName;
}
public void setResponseRenderer(ResponseRenderer responseRenderer)
{
_responseRenderer = responseRenderer;
}
}
[/code]
继续跟踪到上面的方法后可以发现_pageName 的名字:StaleLink,StaleSession
经过查看知道这个名字是从 Framework.library 文件里提取的,打开这个文件可以找到
下面的三句话
[code]
<page name="StaleLink" specification-path="pages/StaleLink.page"/>
<page name="StaleSession" specification-path="pages/StaleSession.page"/>
<page name="Exception" specification-path="pages/Exception.page"/>
[/code]
将上面的代码修改为
[code]
<page name="StaleLink" specification-path="pub/ErrorPage"/>
<page name="StaleSession" specification-path="pub/ErrorPage"/>
<page name="Exception" specification-path="pages/Exception.page"/>
[/code]
搞定,这里说明一下exception 可以通过下面的代码配置,但用同样的配置思想配置其他
两个exception就不行,无奈之下只好修改他的源文件
[code]
<contribution configuration-id="tapestry.InfrastructureOverrides">
<property name="exceptionPageName" value="pub/ErrorPage"/>
</contribution>
[/code]
在网上搜索一下--发现有了更简便的方法来处理这个问题---
自你的application配置文件中加上下面的代码 T4会自动替换自己的基础组建
但注意timeout的类需要继承StaleLink类
[code]
<page name="StaleLink" specification-path="/pub/TimeOut.page"/>
<page name="StaleSession" specification-path="/pub/TimeOut.page"/>[/code]
参考文档:
http://www.blogjava.net/tapestry/archive/2007/01/29/96568.aspx