跳轉到內容

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)" <MacMullin.Jake@saugov.sa.gov.au>; 收件人:"Lu Yanmei" <lu.yanmei@meta.co.jp>, webobjects-dev@omnigroup.com 主題: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 的頁面)試圖渲染到響應中的內容是什麼。

華夏公益教科書