跳转到内容

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 的页面)试图渲染到响应中的内容是什么。

华夏公益教科书