`
dengyin2000
  • 浏览: 1208560 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

打造Tapestry5中的智能的错误页面。

阅读更多
我们一般需要为生产和开发环境准备两套error page。 tapestry在开发环境下的error page做得非常漂亮。 非常详细, 但是在生产环境下就不能暴露太多的信息。 而且error page的外观也需要定制。 这时候tapestry默认的error page就不行了。 所以我们期望的是在开发的时候我们需要tapestry自带的error page, 而在生产环境下我们需要定制自己的error page。

http://wiki.apache.org/tapestry/Tapestry5ExceptionPage
上面这篇文章告诉我们怎样替换掉tapestry自带的error page。 但是我们需要更灵活的方式。

OK, 下面开始写代码。 我们在AppModule class 添加以下代码段。

    // handle RedirectException
    public static RequestExceptionHandler decorateRequestExceptionHandler(
        final Object delegate, final Response response,
        final RequestPageCache requestPageCache, final LinkFactory linkFactory,
        final ComponentClassResolver resolver,
        @Symbol(SymbolConstants.PRODUCTION_MODE) final
        boolean productionMode, final PageResponseRenderer renderer
    	)
    {
        return new RequestExceptionHandler()
        {
            public void handleRequestException(Throwable exception) throws IOException
            {
                // check if wrapped
                Throwable cause = exception;
                if (exception.getCause() instanceof RedirectException)
                {
                    cause = exception.getCause();
                }

                //Better way to check if the cause is RedirectException. Sometimes it's wrapped pretty deep..
                int i = 0;
                while(true){
                    if(cause == null || cause instanceof RedirectException || i > 1000){
                        break;
                    }
                    i++;
                    cause = cause.getCause();
                }

                // check for redirect
                if (cause instanceof RedirectException)
                {
                    // check for class and string
                    RedirectException redirect = (RedirectException)cause;
                    URL url = redirect.getUrl();
                    if (url != null) {
                    	response.sendRedirect(url.toString());
                    	return ;
                    }
                    Link pageLink = redirect.getPageLink();
                    if (pageLink == null)
                    {
                        // handle Class (see ClassResultProcessor)
                        String pageName = redirect.getMessage();
                        Class<?> pageClass = redirect.getPageClass();
                        if (pageClass != null)
                        {
                            pageName = resolver.resolvePageClassNameToPageName(pageClass.getName());
                        }

                        // handle String (see StringResultProcessor)
                        Page page = requestPageCache.get(pageName);
                        pageLink = linkFactory.createPageLink(page, false);
                    }

                    // handle Link redirect
                    if (pageLink != null)
                    {
                        response.sendRedirect(pageLink.toRedirectURI());
                        return;
                    }
                }
               if (productionMode) {
                	Page page = requestPageCache.get("ProductionExceptionReport");
                	ExceptionReporter rootComponent = (ExceptionReporter) page.getRootComponent();
                	rootComponent.reportException(exception);
                	renderer.renderPageResponse(page);
                }else {
	                // no redirect so pass on the exception
	                ((RequestExceptionHandler)delegate).handleRequestException(exception);
                }
            }
        };
    }


我们只要关注64至72行的代码。 64行以上的代码是实现Tapestry4中的RedirectException作用的。我们可以只看64至72行的代码就行了。 这段代码很简单。 如果是productionMode(我们运行时servlet container时加了-Dtapestry.production-mode 参数)的话, 我们去拿"ProductionExceptionReport"页面。 然后调用reportException方法。 最后转到ProductionExceptionReport页面。 如果不是production mode的话,我们使用tapestry默认的RequestExceptionHandler去处理这个异常。 这样tapestry就使用自带的异常页面了。

import java.util.List;

import org.apache.tapestry5.Asset;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.services.ExceptionAnalysis;
import org.apache.tapestry5.ioc.services.ExceptionAnalyzer;
import org.apache.tapestry5.ioc.services.ExceptionInfo;
import org.apache.tapestry5.services.ExceptionReporter;

public class ProductionExceptionReport implements ExceptionReporter {
	
	@Property(write=false)
	private Throwable exception;
	
    @Inject
    private ExceptionAnalyzer analyzer;
    
    @Property
    private List<ExceptionInfo> stack;    

	public void reportException(Throwable exception) {
		this.exception = exception;
        ExceptionAnalysis analysis = analyzer.analyze(exception);
        stack = analysis.getExceptionInfos();		
		sendExceptionByEmail();
	}

	private void sendExceptionByEmail() {
		System.out.println(".......................Send Email ..............");
	}

	@Override
	public Asset[] getCsses() {
		return new Asset[] {getIndexCssAsset()};
	}

}


ProductionExceptionReport页面实现了tapestry5的ExceptionReporter 接口。 这里要注意的是
ExceptionReporter rootComponent = (ExceptionReporter)page.getRootComponent();

你不能把它cast成ProductionExceptionReporter, 这是由tapestry5的classloader超成的。 tapestry5文档中有说明。 你可以在reportException方法中做些事情。 比如发邮件通知管理员。

下面是个简单的error page的模板页面。
<?xml version="1.0" encoding="UTF-8"?>  
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
<t:layout home="false" errorPage="true" showAddNewSite="false" showSideBar="false" title="literal:Error"  xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
	<font color="red">有错误发生,请联系管理员。</font>
	<br/>
	<a t:type="pagelink" t:page="Index">重新开始</a>
</t:layout>


OK。大工告成!

在你开发的环境中启动参数中加上-Dtapestry.production-mode=false


参考:
http://wiki.apache.org/tapestry/Tapestry5ExceptionPage
http://tapestry.apache.org/tapestry5/cookbook/exceptions.html
分享到:
评论

相关推荐

    Tapestry5最新中文入门实例教程

    本文利用Tapestry 5开发一个简单的具有创建/读/更新/删除功能的应用,在创建这个应用的过程中,本文体会到Tapestry带来的开发效率的提升。从多方面来讲解 Tapestry应用,比如应用的页面导航(page navigation)、...

    tapestry5中文文档

    tapestry5组件说明使用及登陆修改等简单实例

    Tapestry5和jQuery集成tapestry5-jquery.zip

    Tapestry5和jQuery集成.使用jQuery以极少的兼容问题完全替换Prototype 和 Scriptaculous库 标签:tapestry5

    tapestry5以上的帮助事例,帮助文档与spring衔接文档

    Tapestry是一个基于控件的框架以致于用它开发Web应用类似开发传统的GUI应用。你用Tapestry开发Web应用时你无需关注以操作为中心的(Operation-centric) Servlet API.引用Tapestry网站上的一句话:"Tapestry用对象...

    tapestry官方中文文档

    Tapestry 4 官方文档中文版本,现在中文资料比较少,和大家共享一下

    Tapestry5最新中文教程

    Drobiazko和R. Zubairov合作撰写了一篇文章,详细介绍Apache Tapestry 版本5——一个...文章向读者展示了创建组件方法,并谈到了Tapestry中的IoC以及Ajax的相关特性 译者 沙晓兰 发布于 2008年7月2日 下午9时30分

    TapeStry5实例教程

    里面用详细实例说明了tapestry5的使用方法 简单 实用 详细 一看就会 在这里提醒一下大家,这个教程讲的是tapestry5而不是tapestry4,如果需要看tapestry4的话,请看我传的另外一本有关tapestry的教程,英文的那本,...

    tapestry教程资料文档合集

    Tapestry5最新中文教程.doc 作者 Renat Zubairov & Igor Drobiazko译者 沙晓兰 发布于 2008年7月2日 下午9时30分 社区 Java 主题 Web框架 ----------------------------------------- Tapestry5.1实例教程.pdf ...

    tapestry官方中文文档及中文字典

    Tapestry 4 官方文档中文版本,包括Tapestry4 Quick Start(2)和Tapestry4 Users Guide(2)两个文档 还有tapestry中文字典等

    Tapestry 5 電子書

    最新Tapestry 5 電子書

    Tapestry 5介绍

    老外的一个ppt介绍Tapestry 5

    Tapestry 5 Building Web Applications.pdf

    Tapestry5 英文版入门技术指导!

    Tapestry5开发环境搭建(Eclipse)

    Tapestry5开发环境搭建(Eclipse),包括服务器搭建。。。

    Tapestry5开发文档手册.doc

    tapestry5组件说明使用等简单实例。Apache Tapestry是一个使用Java语言创建web应用的面向组件的开发框架。Tapestry应用建立在根据组件构建的页面的基础上。这个框架能够提供输入验证(input validation)、本地化/...

    Tapestry 5开发指南(英文)

    Tapestry 5开发指南(英文) Tapestry 5开发指南(英文) Tapestry 5开发指南(英文) Tapestry 5开发指南(英文)

    tapestry页面编辑组件

    tapestry页面编辑组件,可以实现文本框,单选框,多选框和下拉框等的自动生成,并返回改变后的数据。

    tapestry4.02中封装ext的GridPanel组件

    tapestry4.02中封装ext的GridPanel组件

    Tapestry5.0.16_API文档

    Tapestry5.0.16文档和大家一起学习

    关于Tapestry的一些个人总结

    Tapestry简述: Tapestry是一个servle的扩展,它运行于servlet容器(Tomcat)或包含servlet容器的服务器(如Jboss) 通过使用Tapestry,开发者完全不需要使用JSP技术,用户只需要使用Tapestry提供的模板技术即可, ...

    Tapestry5实例(开发步骤)

    Tapestry5实例(开发步骤),环境搭建后必看的实例。。。

Global site tag (gtag.js) - Google Analytics