使用 Java、Struts 2 和 AJAX 下载文件
Posted
技术标签:
【中文标题】使用 Java、Struts 2 和 AJAX 下载文件【英文标题】:File download using Java, Struts 2 and AJAX 【发布时间】:2011-01-08 12:18:27 【问题描述】:我想使用 java、struts2 和 ajax 提供文件下载。
在我的 html 页面上有一个名为“export”的按钮,点击哪个 ajax 调用将执行查询并使用代码创建 .xls 文件,我想将该文件提供给用户下载而不存储它在硬盘上。
有人知道如何在java中使用struts2和ajax吗?
有例子吗?
如果您需要我提供更多详细信息,请告诉我...
谢谢。
amar4kintu
【问题讨论】:
【参考方案1】:在这种情况下,您不必使用 AJAX。只需让您的按钮将表单提交给您的 Struts 操作,并让该操作使用 stream result 类型。
例子:
在您的 Struts XML 中:
<result name="download" type="stream">
<param name="contentDisposition">attachment;filename=report.xls</param>
<param name="contentType">application/vnd.ms-excel</param>
<param name="inputName">inputStream</param>
<param name="bufferSize">1024</param>
</result>
然后您的操作将提供一个public InputStream getInputStream()
来传递数据。
我认为您用来生成 Excel 文件的任何库 (POI?) 都可以将输出写入任意的OutputStream
。
一种将其转换为InputStream
的快捷方式:
// Using Workbook from Apache POI for example...
Workbook wb;
// ...
ByteArrayOutputStream bos = new ByteArrayOutputStream();
wb.write(bos);
InputStream bis = new ByteArrayInputStream(bos.toByteArray());
【讨论】:
您好,我在我的 struts.xml 中添加了以下内容仅供参考,我们可以使用 Annotation 来做同样的事情:
public class MyAction
private InputStream fileInputStream;
private String logoName;
@Action(value="/downloadLogo",
results=
@Result(name="success", type="stream",
params =
"contentType", "application/image/gif",
"inputName", "fileInputStream",
"contentDisposition", "filename=\"$logoName\"",
"bufferSize", "1024"
)
)
public String downloadLogo() throws Exception
logoName = "test.jpg";
fileInputStream = new FileInputStream(new File("DirePath", logoName));
【讨论】:
【参考方案3】:作为 amar4kintu 关于保存为 ExportReport.action 而不是 report.xls 文件的问题的后续行动,如果您的 struts.xml 文件中未遵循以下格式,则会在 IE 中发生这种情况:
<result name="download" type="stream">
<param name="contentDisposition">attachment;filename="$flashcardSetBean.title.xlsx"</param>
<param name="contentType">application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</param>
<param name="inputName">inputStream</param>
<param name="bufferSize">1024</param>
</result>
似乎contentDisposition
行特别必须表明该文件是一个附件并且文件名用引号括起来。
【讨论】:
【参考方案4】:我会在 Action 类上使用这种注释:
@Result(name = "success", type= StreamResult.class,
params = "contentType", "application/vnd.ms-excel",
"contentDisposition", "attachment; filename=report.xls",
value = "reportFileStream"
)
【讨论】:
【参考方案5】:下面解释了一种将输出流传输到输入流的更好方法 as opposed to the response by ZoogieZork above
InputStream is = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream((PipedInputStream) is);
wb.write(out);
这种方法的优点是整个缓冲区不存储在内存中,而是使用一个小的内部循环缓冲区进行管道传输。这在内存和 CPU 开销方面都更好。
参考: Convert a Java OutputStream to an InputStream
【讨论】:
【参考方案6】:atlast,我能够解决它如下..
我在我的动作类函数中写了以下行,我能够下载名称为 report.xls
而不是 ExportReport.action
的文件。我不知道确切..为什么?
response.setHeader("Content-Disposition","attachment;filename=rpt.xls");
以下内容在我的struts.xml
文件中。我从中删除了<contentDispositin>
参数,因为它不能从struts.xml
文件中工作,我将它放在我的操作Java 文件中,如上所述。
<result name="success" type="stream" >
<param name="inputName">fileStream</param>
<param name="contentType">application/vnd.ms-excel</param>
<param name="bufferSize">1024</param>
</result>
希望这会对某人有所帮助。
谢谢。
amar4kintu
【讨论】:
以上是关于使用 Java、Struts 2 和 AJAX 下载文件的主要内容,如果未能解决你的问题,请参考以下文章
struts2发送ajax的几个问题(不使用struts2-json-plugin的情况下)
Java基础101 Struts2下的 jquery+ajax+struts 技术实现异步刷新功能