【问题标题】:Downloaded file is 0 bytes, what is wrong with it?下载的文件是0字节,这是怎么回事?
【发布时间】:2012-02-27 07:37:09
【问题描述】:

需要帮助弄清楚为什么下载的文件大小为 0 字节?单击下载按钮时,页面会弹出一个保存或打开对话框,当我选择保存时,某个位置会保存文件,但它是一个空文件。有什么问题?

JSP 文件

<form target="_blank" method="get" action="/csm/download.action" >
    <input type="hidden" id="absFileName" name="absFileName" value="">
    <input type="submit" class="btn" id="btnDownloadConfig" value="Download Configuration"/>
</form>

Struts.xml

<action name="download" class="com.abc.csm.actions.DownloadConfiguration">
    </action>

我的下载代码

String filePath = ServletActionContext.getServletContext().getRealPath("/")
filePath+=executionResponse

def splits=filePath.split("/")

cfgfileFileName=splits[splits.length-1]

println filePath+", "+cfgfile+", "+cfgfileFileName+", "+executionResponse

File f=new File(filePath)

println("Does file Exists? "+f.exists())

InputStream  inputStream = new FileInputStream(f)

response.setContentType("APPLICATION/xml")

response.addHeader("Content-Disposition", "attachment; filename=\""+cfgfileFileName+"\"")

我在控制台中的输出

E:\Tomcat 6\webapps\csm\files//1123/Infa9_1_csmclientbeetle.xml, Infa9_1_csmclientbeetle.xml, files//1123/Infa9_1_csmclientbeetle.xml
Does file Exists? true

我在 tomcat webapps 中的文件位置

E:\Tomcat 6\webapps\csm\files\1123

更新

我找到了一个类似的 question 对我有帮助

这就是我对 InputStream 所做的

FileInputStream ins = new FileInputStream(f)
    OutputStream out = response.getOutputStream()
    byte[] buf = new byte[1024]
    int len = 0
    while ((len = ins.read(buf)) >= 0)
    {
        out.write(buf, 0, len)
    }
    ins.close()
    out.close()

【问题讨论】:

  • 你的代码真的任何与inputstream相关的事情吗?
  • 我不知道你为什么要这样做,而使用流结果 (struts.apache.org/2.3.1/docs/stream-result.html) 可以以更干净的方式完成。
  • @Umesh:你有一个例子,我可以在哪里看?谢谢
  • @AbhishekSimon:查看我更新的评论。我相信你没有使用 S2 的真正力量。
  • @Umesh:在那个链接中,它设置了文件名&lt;param name="contentDisposition"&gt;attachment;filename="document.pdf"&lt;/param&gt;,但在我的情况下,我需要动态设置它

标签: java groovy struts2


【解决方案1】:

我相信您可以使用 Stream result 类型中的 S2 构建以更灵活的方式处理您的下载功能。您只需在您的操作类中定义 fileInputStream 即可用于下载您的内容。

您可以在配置文件中动态设置所有其他内容。这是示例代码

public class DownloadAction extends ActionSupport{

    private InputStream fileInputStream;

    public InputStream getFileInputStream() {
        return fileInputStream;
    }

    public String execute() throws Exception {
        fileInputStream = new FileInputStream(new File("location of your file"));
        return SUCCESS;
    }
}

您可以在 struts.xml 文件中使用流结果

<action name="download" class="com.abc.csm.actions.DownloadConfiguration">
    <result name="success" type="stream">
      <param name="contentType">application/octet-stream</param>
      <param name="inputName">fileInputStream</param>
      <param name="contentDisposition">attachment;filename="fileABC.txt"</param>
      <param name="bufferSize">1024</param>
    </result>
   </action>

以上所有参数,在你的动作标签内都可以动态设置。您只需在动作类中定义属性并在配置中使用它们。

例如,如果您想动态设置内容类型,请在您的操作类中使用其 getter 和 setter 创建一个属性,并在您的执行/任何其他方法中设置此属性的值。 您需要在 struts.xml 文件中使用动态属性值,例如

 <action name="download" class="com.abc.csm.actions.DownloadConfiguration">
        <result name="success" type="stream">
          <param name="contentType">${contentType}</param>
          <param name="inputName">fileInputStream</param>
          <param name="contentDisposition">attachment;filename="fileABC.txt"</param>
          <param name="bufferSize">1024</param>
        </result>
       </action>

有关可以在流结果中设置的各种属性的详细信息,请参阅官方文档

stream-result

【讨论】:

  • 对于一个新的 struts2 用户来说,很好的完整答案,在 struts2 标签 Umesh 上的工作做得很好,按照这个速度,你可能会成为第一个在这个标签中获得银奖的人。
  • @Quaternion:谢谢夸奖:)
【解决方案2】:
InputStream  inputStream = new FileInputStream(f)
response.setContentType("APPLICATION/xml")
response.addHeader(
  "Content-Disposition", "attachment; filename=\""+cfgfileFileName+"\"")

就这些了吗?你把文件发到哪里?你可能会错过类似的东西

IOUtils.copy(inputStream, response.getOutputStream())

【讨论】:

    【解决方案3】:

    尝试将其添加到您的编写器实例中:

    myWriter.flush();
    

    【讨论】:

    • 什么作家?那会有什么不同?
    • 当将数据写入文件或其他地方时,如套接字或其他东西,您应该将输入流包装到更高级的东西,如 FileWriter 类,以使其更容易处理。 FileWriter 类有一个名为 flush() 的方法,它可以立即将流中的数据写入文件、套接字等。这是必需的,因为数据并不总是在接收到的同时写入,流中包含它缓冲区,所以为了确保数据被写入,你应该使用 flush() 方法。
    • flush() 自动发生在out.close()。添加一个显式的并不能解决这个问题。
    猜你喜欢
    • 2011-09-26
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    相关资源
    最近更新 更多