我在服务器中有一个zip文件。我想点击链接下载该文件。
有没有办法在JSF或PrimeFaces中创建一个下载zip文件的链接,比如客户端下面的HTML5 download
属性?
<a href="/images/myw3schoolsimage.jpg" download>
答案 0 :(得分:8)
HTML5 download
属性与它无关。它只允许您指定应出现在另存为对话框中的备用文件名。
E.g。
<a href="foo.zip" download="bar.zip" />
将显示另存为对话框,其中bar.zip
为文件名,但实际上提供的内容为foo.zip
。请注意,bar.zip
并不一定需要存在于服务器中。
关于您的具体问题,有几种方法可以在JSF Web应用程序中提供文件下载。
只需将该文件放入公共网页内容文件夹即可。
WebContent
|-- META-INF
|-- WEB-INF
|-- files
| `-- foo.zip
|-- page.xhtml
:
然后您可以将其称为:
<a href="#{request.contextPath}/files/foo.zip">download foo.zip</a>
或者,如果它是外部文件夹而您无法将其移动到公共网页内容中,那么只需告诉服务器发布它即可。例如。当您在/path/to/files
路径中拥有所有这些文件并且您正在使用Tomcat服务器时,请将以下内容添加到Tomcat <Host>
的{{1}}元素中:
/conf/server.xml
然后您可以将其称为:
<Context docBase="/path/to/files" path="/files" />
或者,如果您无法以某种方式控制服务器配置,或者无法确定将任意文件夹作为新的Web上下文发布的特定于服务器的方式,或者它代表一个临时存储文件夹,您可以#39;而不是发布到Web上,然后创建一个完成工作的Web servlet。将缓存和恢复留在外面考虑,它很简单:
<a href="/files/foo.zip">download foo.zip</a>
您可以像#1一样引用它:
@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 :(得分:3)
虽然这是一个老问题,但我想将此添加到@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获取路径遍历攻击的更多解决方案。
希望它能帮助一些开发人员......