【问题标题】:Servlet for download files from a specific folder?用于从特定文件夹下载文件的 Servlet?
【发布时间】:2013-03-23 20:19:43
【问题描述】:

我是 JAVA 技术的新手,尤其是 Servlet。我需要制作一个 Web 应用程序项目,该项目具有上传和下载文件到服务器(tomcat)的功能。我已经有一个上传 servlet,它工作正常。

我也有一个下载 servlet,在互联网上找到。但问题是这个 servlet 只允许下载一个特定的文件,并且这个特定文件的路径在 servlet 中给出。我需要让客户看到我上传文件夹的全部内容,并选择他想从这个文件夹下载哪个文件。

下载servlet的代码是这样的:

import java.io.DataInputStream; 
import java.io.File; 
import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.ServletContext; 
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



 public class DownloadServlet extends javax.servlet.http.HttpServlet implements
            javax.servlet.Servlet {
        static final long serialVersionUID = 1L;
        private static final int BUFSIZE = 4096;
        private String filePath;`

public void init() {
    // the file data.xls is under web application folder

    filePath = getServletContext().getRealPath("")  + File.separator;// + "data.xls";
}

protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    File file = new File(filePath);
    int length   = 0;
    ServletOutputStream outStream = response.getOutputStream();
    ServletContext context  = getServletConfig().getServletContext();
    String mimetype = context.getMimeType(filePath);

    // sets response content type
    if (mimetype == null) {
        mimetype = "application/octet-stream";
    }
    response.setContentType(mimetype);
    response.setContentLength((int)file.length());
    String fileName = (new File(filePath)).getName();

    // sets HTTP header
    response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

    byte[] byteBuffer = new byte[BUFSIZE];
    DataInputStream in = new DataInputStream(new FileInputStream(file));

    // reads the file's bytes and writes them to the response stream
    while ((in != null) && ((length = in.read(byteBuffer)) != -1))
    {
        outStream.write(byteBuffer,0,length);
    }

    in.close();
    outStream.close();
}
}

JSP 页面是这样的:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
   pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Download Servlet Test</title>
</head>
<body>
Click on the link to download: <a href="DownloadServlet">Download Link</a>
</body>
</html>

我搜索了很多 servlet,但它们都是这样的……它们只允许下载特定的文件。 谁能帮我? 非常感谢!

【问题讨论】:

  • 你试过什么?您是否对下载的代码进行了任何修改?你做了哪些改变?什么有效?什么没有?除了寻找可以下载的完整解决方案之外,您是否进行过任何研究?只是从互联网上复制和粘贴代码不会让你走得太远,有时你必须自己做。
  • @Adrian 感谢您的回复。正如我所说,上面的代码仅适用于在 Servlet 中下载作为其路径的文件。在此示例中,在 init() 函数中。我试图为 filePath 属性提供一个路径作为字符串。例如:filepath = "C://Apache//Application//data//",但我收到一个错误:访问被拒绝。我尝试了其他方法:使用文件属性和 listFiles 方法在我的 JSP 中创建文件夹内容列表,然后我编写 '
    ' 但这仅适用于 IE将目标另存为。
  • @user2236267 尝试使用不同的路径,例如 C:\\external\\path。此外,请确保您的用户有足够的权限写入该文件夹。我没有包含该信息,因为我假设您已经知道了。
  • 我对 JAVA 编程非常陌生。我尝试了很多方法来解决我的问题,但我没有找到任何解决方案。我会尝试更多,如果我能找到任何解决方案,我会在这里发布。

标签: java servlets upload download


【解决方案1】:

由于您正在使用doGet 方法处理数据,因此您可以将参数传递给servlet,您可以在其中指明要下载的文件的名称。为此,您应该假设文件名存在于您的基本路径中。代码可以是这样的:

HTML

<body>
    Click on the link to download:
    <a href="DownloadServlet?fileName=data.xls">Download Link</a>
</body>

Java Servlet 代码:

protected void doGet(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
    //retrieving the parameter by its name
    String fileName = request.getParameter("fileName"); //this will return `data.xls`
    //using the File(parent, child) constructor for File class
    File file = new File(filePath, fileName);
    //verify if the file exists
    if (file.exists()) {
        //move the code to download your file inside here...

    } else {
        //handle a response to do nothing
    }
}

请注意,由于代码现在使用 File(String parent, String child) 构造函数,您的 filePath 不应再包含分隔符(这将由 Java 处理):

public void init() {
    // the file data.xls is under web application folder
    filePath = getServletContext().getRealPath("");
}

【讨论】:

  • 非常感谢您的回答我尝试了您的代码,但无法使其工作。
  • @user2236267 试试看。如果它满足您的需求,请在信誉下方标记检查,以便将帖子标记为答案。
  • 我是 stackoverflow 的新手。我需要一些时间来处理这个问题。我试图对你的回答进行投票,但它告诉我我需要 15 名声望。我想用我的新代码回复,但它告诉我我的评论太大了。
  • 我不明白客户端如何看到我上传文件夹的全部内容。那里有很多文件..比如说 test.txt,test.pdf,image.jpg。我希望用户选择要下载哪些文件。不仅仅是一个,在 html 页面中作为参数给出。
  • 更清楚地说:客户必须看到我文件夹中每个文件的不同链接。然后,他必须单击与他要下载的文件关联的链接。谢谢!
【解决方案2】:

你可以这样做

     public void doGet(HttpServletRequest req, HttpServletResponse res){
     res.setContentType("text/html);
      PrintWriter out=response.getWriter();
      String fileName="home.txt";
      String filePath="d:\\";
    response.setContentType("APPLICATION/OCTET-STREAM");
    response.setHeader("Content-Disposition","attachment;fileName=\""+fileName+"\"");
    int i;
    FileInputStream file=new FileInputStream(filePath +fileName);
    while((i=file.read()) !=-1){
      out.write(i);
   }
    file.close();
   out.close();
}

【讨论】:

    【解决方案3】:
      // get MIME type of the file
        String mimeType = context.getMimeType(fullPath);
        if (mimeType == null) {
            // set to binary type if MIME mapping not found
            mimeType = "application/octet-stream";
        }
        System.out.println("MIME type: " + mimeType);
    
        // set content attributes for the response
        response.setContentType(mimeType);
        response.setContentLength((int) downloadFile.length());
    

    这个更详细以及如何改进的问题:https://stackoverflow.com/questions/41914092/how-change-servlet-which-download-single-file-but-can-folderfew-files-in-fold

    【讨论】:

      猜你喜欢
      • 2015-09-19
      • 2022-08-05
      • 2015-11-09
      • 1970-01-01
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多