WebObjects/Web 应用程序/开发/示例/返回文件
要从超链接返回文件,最简单的方法似乎是在 WOComponent 中覆盖 appendToResponse,以返回该文件作为响应,而不是让 WOComponent 从 .html/.wod 文件生成自己的响应
public void appendToResponse(WOResponse aResponse, WOContext aContext) { //Use whatever mime-type you need for content-type: //"text/csv" is just an example. aResponse.setHeader("text/csv", "content-type"); //Assuming 'data' is a Java byte[] array. But //You can do whatever you want to wind up with //an NSData of content. aResponse.setContent( new NSData( data ) ); aResponse.setHeader("filename=MyFilename.xls", "Content-Disposition"); //or, if you want the link to "force" a SaveAs dialog... //aResponse.setHeader("attachment;filename=MyFilename.xls", "Content-Disposition");
其他人报告:我们有以下代码用于下载生成的 pdf...
public void appendToResponse(WOResponse aResponse, WOContext aContext) { super.appendToResponse(aResponse, aContext); //aResponse.setHTTPVersion("HTTP/1.1"); aResponse.disableClientCaching(); aResponse.removeHeadersForKey("Cache-Control"); aResponse.removeHeadersForKey("pragma"); aResponse.setHeader("application/pdf", "content-type"); aResponse.setHeader("inline; attachment; filename=\"" + fileName + ".pdf\"", "content-disposition"); aResponse.setHeader(Integer.toString(resultData.length()), "content-length"); aResponse.setContent(resultData); }
用于修复 IE 问题(至少对我们来说)的关键行是...
aResponse.disableClientCaching(); aResponse.removeHeadersForKey("Cache-Control"); aResponse.removeHeadersForKey("pragma");
您可能想尝试
public void appendToResponse( WOResponse r, WOContext c ) { fileName = "test.txt"; r.setHeader( contentType + "; name=\"" + fileName + "\"", "Content-Type" ); r.setHeader( "inline; filename=\"" + fileName + "\"", "Content-Disposition"); r.setContent( data ); }
虽然根据 RFC2183,您的代码应该可以正常工作,但我发现来自一个无名垄断的某些浏览器只会查看 RFC1341 中的旧位置以获取文件名,该位置位于 Content-Type 标头中,而不是(或至少仅在)Content-Disposition 标头中。
如果您主要希望他们下载文件,您可能希望将其设为
public void appendToResponse( WOResponse r, WOContext c ) { fileName = "test.txt"; r.setHeader( contentType + "; name=\"" + fileName + "\"", "Content-Type" ); r.setHeader( "attachment; filename=\"" + fileName + "\"", "Content-Disposition"); r.setContent( data ); }
以及来自邮件列表的另一个来回....
我在显示 PDF 文件时遇到问题 [....] 我可以通过点击“下载消息提醒”上的[保存]来成功保存文件,但当我点击[打开]时,Acrobat 运行并显示错误消息“没有这样的文件”,无法打开 PDF 文件。
发件人:"MacMullin, Jake (DCS)" <[email protected]>; 收件人:"Lu Yanmei" <[email protected]>, [email protected] 主题:RE: 无法打开 PDF 文件 日期:2003 年 5 月 30 日星期五 09:06:57 +0930
我遇到了完全相同的问题。结果发现这与您使用的标头有关。我发现这种组合效果最好
// set the PDF content and header response.setContent(outData); response.appendHeader("application/pdf", "Content-Type"); response.appendHeader(outData.length()+"", "Content-Length"); response.appendHeader("inline;filename=\"file.pdf\"", "Content-Disposition");
以及来自邮件列表的另一个来回....
我在浏览器中显示 PDF 文件时遇到了问题 [....] 我可以发送简单的文本文件以在浏览器中打开,但 pdf 显示为乱码。我不能依赖用户拥有插件,有没有办法在浏览器中显示它?否则是否有办法将 pdf 转换为 html 并将其显示在浏览器中。
r.appendHeader("application/pdf", "Content-type"); r.setHeader(Integer.toString(myData.length()), "content-length"); r.appendHeader("application;filename=\"dockconcepts.pdf\"", "Content-Disposition"); r.appendContentCharacter('\n'); r.appendContentData(new NSData(myData));
如果要响应表单提交返回文件(并在 Windows 上的 IE 中运行),您需要通过在 WOBuilder 中向表单添加“方法”绑定,将表单的“方法”从“POST”更改为“GET”。
我强烈建议使用 setHeader 方法而不是 appendHeader 方法,以确保现有的内容类型将被文件返回组件覆盖。如果已存在内容类型,appendHeader 不会更改内容类型值,这会导致不可预测的结果。--Hschottm 2007 年 1 月 16 日 14:24(UTC)
如果您试图从子组件执行此操作,则需要使用 setContentInputStream 而不是 setContent。前者的文档说“只返回 InputStream 中的数据——任何已添加或设置的数据(作为字符串或 NSData)都将被忽略”,而后者可以在页面生命周期的后期被覆盖或追加。例如,我有一个通用的组件,它运行一个报表并将该报表作为 PDF 提供给用户。我想在我的 ListPeople 页面中包含该组件,如下所示
PrintLink : ReportDownloader { title = "Download these results"; fileName = "PersonList.pdf"; data = personList.displayedObjects; definition = "personlist"; }
在 ReportDownloader.java 中,doReport() 处理对“下载这些结果”链接的点击并构建报表。
public void doReport() { // ...snip... // Run the report and put the resulting PDF into the byte array pendingResponse // ...snip... }
如上所述,覆盖的 appendToResponse 方法负责将报表实际写入响应中。
public void appendToResponse(WOResponse aResponse, WOContext aContext) { super.appendToResponse(aResponse, aContext); if (pendingResponse != null) { //aResponse.setContent(pendingResponse); ByteArrayInputStream in = new ByteArrayInputStream(pendingResponse); aResponse.setHeader("application/pdf", "Content-type"); aResponse.setHeader("inline; filename=" + fileName, "Content-disposition"); aResponse.setContentStream(in, 512, (long)pendingResponse.length); } }
创建 ByteArrayInputStream 并设置响应以使用它可以确保 PDF 内容是响应中唯一返回的内容,无论父页面(包含 ReportDownloader 的页面)试图渲染到响应中的内容是什么。