ZK Web应用程序可以指定错误发生时该做什么。错误是由异常引起的,而应用程序没有捕获到这个异常。
在两种情况下可能会抛出异常:加载页面和更新页面[59]。
若加载ZUML页面时抛出了一个未捕获的异常,此异常会直接由Web服务器处理。换言之,这和其它页面的处理没有区别,例如JSP。
默认情况下,Web服务器会使用一个错误页面来显示错误信息及栈跟踪(stack trace)。
通过在WEB-INF/web.xml
文件内指定错误页面,你可以定制错误处理,如下。细节请参考Java Servlet Specification。
<!-- web.xml --> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/WEB-INF/sys/error.zul</location> </error-page>
那么,当加载页面时发生一个错误,Web服务器会转向你指定的错误页面,/error/error.zul
。转发之后(Upon forwarding),Web 服务器会立即将一套请求属性传递到错误页面以描述发生了什么。这些属性如下。
请求属性 |
类型 |
---|---|
javax.servlet.error.status_code |
java.lang.Integer |
javax.servlet.error.exception_type |
java.lang.Class |
javax.servlet.error.message |
java.lang.String |
javax.servlet.error.exception |
java.lang.Throwable |
javax.servlet.error.request_uri |
java.lang.String |
javax.servlet.error.servlet_name |
java.lang.String |
然后,在错误页面内,通过使用这些属性,你可以显示你的定制信息。例如,
<window title="Error ${requestScope['javax.servlet.error.status_code']}"> Cause: ${requestScope['javax.servlet.error.message']} </window>
[提示]:错误页面可以为任何类型的 servlet。除了ZUL,可以使用JSP或任何你喜欢的页面。
[提示]:转发之后, 错误页面会被作为主页面展示,所以你不需要指定主窗口指定模态(modal)或 overlapped 模式(mode)(如果有的话)。
若当更新ZUML页面(亦=一个事件监听器正在执行时)时抛出了一个未被捕获的异常,此异常会由ZK更新引擎(ZK Update Engine)处理。默认情况下,它只会要求浏览器端显示一个警告对话框来告诉用户。
你可以在WEB-INF/zk.xml
文件内指定错误页面以定制错误处理,如下。参考the Developer's Reference 的附录B(Appendix B)。
<!-- zk.xml --> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/WEB-INF/sys/error.zul</location> </error-page>
那么,当在事件监听器内发生一个错误时,ZK更新引擎会使用你指定的错误页面,/error/error.zul
,创建一个对话框。
就像加载一个页面时的错误处理,你可以指定多个<error-page>
元素。其中的每个元素都与一个不同的异常类型(<exception-type>
元素的值)相关联。当发生一个错误时,ZK将会逐个寻找错误页面,直到异常类型匹配。
另外,ZK将一套请求属性传递到错误页面来描述发生了什么。这些属性如下。
请求属性 |
类型 |
---|---|
javax.servlet.error.exception_type |
java.lang.Class |
javax.servlet.error.message |
java.lang.String |
javax.servlet.error.exception |
java.lang.Throwable |
例如,你可以指定下列的内容作为错误页面。
<window title="Error ${requestScope['javax.servlet.error.status_code']}" width="400px" border="normal" mode="modal"> <vbox> KillerApp encounters a fatal error, ${requestScope['javax.servlet.error.message']}. The error is recorded and we will look at it and fix it soon. <hbox style="margin-left:auto; margin-right:auto"> <button label="Continue" onClick="spaceOwner.detach()"/> <button label="Reload" onClick="Executions.sendRedirect(null)"/> </hbox> </vbox> <zscript> org.zkoss.util.logging.Log.lookup("Fatal").log( requestScope.get("javax.servlet.error.exception")); </zscript> </window>
[提示]: 错误页面是在引起错误的相同卓面内被创建的,所以你可以从其中获取相关的信息。
[提示]:从2.3.1开始,ZK不会自动将根窗口作为模态(modal),因为一些应用程序或许并不倾向于使用modal窗口。若你倾向于使用模态窗口,可以指定为模态 模式,就像前面所示的例子那样。
每个device类型都有其自己的一套错误页面。为了为ZK mobile设备指定一个错误页面(支持MIL 的移动设备),你必须使用mil
指定device-type
元素,如下所示。
<!-- zk.xml --> <error-page> <device-type>mil</device-type> <exception-type>java.lang.Throwable</exception-type> <location>/WEB-INF/sys/error.zul</location> </error-page>
[提示]: 若忽略了device-type
元素,则假定为ajax。换言之,为Ajax浏览器指定了一个错误页面。
<device-type>ajax</device-type> <!-- ajax is the default -->