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