2015-01-06 85 views
1

我在服务器中有一个zip文件。我想点击链接下载该文件。链接下载JSF中的zip文件

有没有办法创建一个链接来下载JSF或PrimeFaces的zip文件,如下面的客户端HTML5 download属性?

<a href="/images/myw3schoolsimage.jpg" download> 
+0

为了您的知识,采取'P A的样子:fileDownload',它可以帮助你一天:http://www.primefaces.org/showcase/ui/file /download.xhtml – Pellizon

+0

@Pellizon:只有在磁盘上没有具体文件时才有用,但在JSF托管bean中只有'InputStream'或'byte []'。 – BalusC

回答

6

HTML5 download属性与它无关。它只是允许你指定一个替代文件名,它应该出现在另存为对话框中。

E.g.

<a href="foo.zip" download="bar.zip" /> 

将显示另存为bar.zip作为文件名对话框,但实际上提供的foo.zip内容。请注意,bar.zip不一定需要存在于服务器中。


至于您的具体问题,有几种方法可以在JSF Web应用程序中提供文件下载。

  1. 只需将该文件放入公共Web内容文件夹即可。

    WebContent 
    |-- META-INF 
    |-- WEB-INF 
    |-- files 
    | `-- foo.zip 
    |-- page.xhtml 
    : 
    

    然后,你可以参考它:

    <a href="#{request.contextPath}/files/foo.zip">download foo.zip</a> 
    
  2. 或者,如果它是一个外部文件夹,您无法将其迁移到公共网页内容,然后就告诉服务器发布。例如。当你有/path/to/files路径和您正在使用Tomcat服务器所有这些文件,然后添加以下到Tomcat的/conf/server.xml<Host>元素:

    <Context docBase="/path/to/files" path="/files" /> 
    

    然后,你可以参考它:

    <a href="/files/foo.zip">download foo.zip</a> 
    
  3. 或者,如果您无法控制服务器配置,或者无法确定将任意文件夹发布为新的Web上下文的特定于服务器的方式,还是代表您不希望发布到Web中的临时存储文件夹,然后创建一个可以完成这项工作的web servlet。离开缓存和恢复之外的考虑,它是那样简单:

    <a href="#{request.contextPath}/files/foo.zip">download foo.zip</a> 
    
2

尽管这是一个老问题,我想:

@WebServlet("/files/*") 
public class FileServlet extends HttpServlet { 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     String filename = request.getPathInfo().substring(1); 
     File file = new File("/path/to/files", filename); 
     response.setHeader("Content-Type", getServletContext().getMimetype(filename)); 
     response.setHeader("Content-Length", String.valueOf(file.length())); 
     response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); 
     Files.copy(file.toPath(), response.getOutputStream()); 
    } 

} 

你可以参考它作为#1的相同方式将其添加到@ BalusC的答案完整性(由于低信誉导致的评论):@BalusC(带有@WebServlet)的第三种解决方案可能导致'路径遍历攻击',如果复制粘贴。

您可以使用URL尝试攻击(对于Linux服务器):

<yourApplicationURLUntilContextPath>/files/%C0%AE/%C0%AE/%C0%AE/%C0%AE/%C0%AE/%C0%AE/%C0%AE/%C0%AE/%C0%AE/%C0%AE/etc/passwd 

对于这个问题的各种解决方案。其中之一是,将文件复制到输出流之前添加下面的检查:

if(!file.getAbsolutePath().equals(file.getCanonicalPath())) 
{ 
response.sendError(404); 
} 

你可以参考的link更多的解决方案,路径遍历攻击。

希望它可以帮助开发者的...