我正在尝试实现Paul Calhoun的Apache FOP解决方案,用于从Xpages创建PDF(来自Notes In 9#102).我在尝试运行执行处理的xAgent时遇到以下java异常 - >在OutputStream已被使用时无法获取Writer
我从Paul的代码中做的唯一更改是更改包名称.当SSJS行发生异常时我已经隔离了: var jce: DominoXMLFO2PDF = new DominoXMLFO2PDF(); 所有那行都是实例化类,没有自定义构造函数.我不相信这是代码本身,但有些配置问题.SSJS代码在beforeRenderResponse事件中应该是,我没有更改xAgent上的任何内容.
我已经将Paul的示例数据库中的jar文件复制到了我的文件中,我已经验证了两个数据库之间的构建路径是相同的.一切都编译好(在我完成所有这些之后.)此异常似乎只是一个xpages异常.
Tim*_*ony 11
以下是此错误的真实情况:
XPage本质上是servlet ......在XPage中发生的一切只是在servlet引擎之上的层.基本上有两种类型的数据,servlet可以将这些数据发送回启动连接的任何内容(例如浏览器):文本和二进制.
普通的XPage发送文本 - 特别是HTML.某些xAgent还会发送文本,例如JSON或XML.但是,在任何这些场景中,Domino都使用Java Writer发送响应内容,因为Writer已针对发送Character数据进行了优化.
当我们需要发送二进制内容时,我们使用OutputStream代替,因为流被优化用于发送通用字节数据.因此,如果我们发送PDF,DOC/XLS/PPT,图像等,我们需要使用流,因为我们发送的是二进制数据,而不是文本.
捕获(你很快就会看到,这是双关语)是我们每个响应只能使用一个.
一旦任何HTTP客户端被告知响应的内容类型是什么,它就如何处理该内容做出假设.因此,如果你告诉它application/pdf,它期望只接收二进制数据.相反,如果你告诉它application/json,它期望只接收字符数据.如果响应包含与承诺的内容类型不匹配的任何数据,则几乎总是使整个响应无效.
因此,Domino以其无限的智慧保护我们不会因为只允许我们在一个请求中发送一个或另一个而犯下这个错误,并且如果我们违反该规则则抛出异常.
不幸的是......如果我们在尝试发送二进制内容时代码中有任何异常,那么Domino想要向消费者报告...它试图调用输出编写器发送HTML报告,说明出错了.除了我们已经获得输出流的句柄之外,因此不允许Domino在输出编写器上获取句柄,因为这会违反其自己的规则,而不是每个响应使用一个.反过来,这会抛出您报告的异常,掩盖实际导致问题的异常(在您的情况下,可能是ClassNotFoundException).
那么我们如何确保我们看到真正的问题,而不是这种误导?我们try:
try {
/*
* Move all your existing code here...
*/
} catch (e) {
print("Error generating dynamic PDF: " + e.toString());
} finally {
facesContext.responseComplete();
}
Run Code Online (Sandbox Code Playgroud)
这是首选方法有两个原因:
print它发送到控制台和日志,你也可以把它扔到OpenLog,或者你喜欢的任何日志记录机制).这意味着Domino不会尝试向用户报告错误,因为我们已经承诺我们已经向自己报告了错误.facesContext.responseComplete()调用(最终告诉Domino不要将其自己的任何内容发送到finally块),这可以确保它将被执行.如果我们把它留在try块中,如果发生异常就会跳过它,因为我们直接跳到catch...所以即使Domino没有报告我们的异常,因为我们抓住了它,它仍然试图调用响应作家,因为我们没有告诉它不要.如果你按照上面的模式,你的代码有问题,那么浏览器将收到一个不完整或损坏的文件,但是日志会告诉你出了什么问题,而不是报告一个与根本原因无关的错误.问题.
| 归档时间: |
|
| 查看次数: |
1371 次 |
| 最近记录: |