使用html锚标记在struts2中下载文件

时间:2013-04-12 15:11:42

标签: java-ee struts2 download

在普通HTML标记中,可以使用锚标记生成下载链接,如:

<a href="www.example.com/somefile.zip">DOWNLOAD</a>

在struts2中,我将文件名和文件URL存储在数据库中。 然后,在JSP文件中,填充下载链接,如:

<s:iterator value="fileList">
<a href='<s:property value="fileURL"/>'> <s:property value="fileName"/> </a>
</s:iterator>

通过这种方式,填充文件名及其链接。当我在链接上鼠标悬停时,我可以在浏览器的状态栏中看到正确的文件URL。但是当我单击链接时,现在会显示下载对话框。我搜索了互联网,他们告诉我们使用FileInputStream。 我的问题是,是否可以生成下载链接而不是使用FileInputStream?

1 个答案:

答案 0 :(得分:3)

使用Struts2,您有ActionResult s。

因此,您需要Action映射到您的链接,我们可以将其称为download_file.do

你创建你的链接列表,传入一个参数告诉struts2要下载哪个文件(允许任意文件是危险的,所以文件名可能会很好)。

<s:iterator value="fileList">
   <s:a action="download_file"> 
      <s:property value="fileName"/>
      <s:text name="my.link"/>
   </a>
</s:iterator>

现在,在您的Action中,您需要像往常一样设置fileName

execute方法中获得fileName后,向InputStream打开File并为其提供getter。您可能还想获取文件的大小以及要下载的名称。

让我们假设InputStream的getter是getFileToDownload,大小的getter是getFileSize

您需要为内容处置提供一个getter,这将设置下载文件的名称,如:

public String getContentDisposition() {
    return "attachment;filename=\"" + fileName + "\"";
}

还有MIME类型的getter,类似于

public String getContentType() {
    return "text/plain";
}

显然将MIME设置为正确的类型。

所以你的基本Action看起来像这样

public class MyAction extends ActionSupport {

    private final File baseDownloadDir = new File("somewhere");
    private String fileName;
    private InputStream inputStream;
    private long fileSize;

    @Override
    public String execute() throws Exception {
        /*
         *This is a security hole begging to be exploited.
         *A user can submit "../../../../someImportantFile"
         *and potentially download arbitrary files from the server.
         *You really need to do some validation on the input!
         */ 
        final File fileToDownload = new File(baseDownloadDir, fileName);
        fileSize = fileToDownload.length();
        inputStream = new FileInputStream(fileToDownload);
        return "downloadFile";
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public long getFileSize() {
        return fileSize;
    }

    public InputStream getFileToDownload() {
        return inputStream;
    }

    public String getContentDisposition() {
        return "attachment;filename=\"" + fileName + "\"";
    }

    public String getContentType() {
        return "text/plain";
    }
}

然后返回结果名称,我们称之为downloadFile

在您的操作映射中,您需要将结果映射到StreamResult,这是一个XML示例

<result name="downloadFile" type="stream">
    <param name="inputName">fileToDownload</param>
    <param name="contentType">${contentType}</param>
    <param name="contentLength">${fileSize}</param>
    <param name="contentDisposition">${contentDisposition}</param>
    <param name="contentCharSet">UTF-8</param>
    <param name="allowCaching">true</param>
</result>

您可能想要更改字符集。