2013-04-02 67 views
6

我是JAVA技術的新手,尤其是Servlets.I需要製作一個Web應用程序項目,它具有上傳和下載文件到/從服務器(tomcat)。我已經有一個上傳servlet,它工作正常。Servlet從特定文件夾下載文件?

我也有一個下載servlet,可以在internet上找到。但問題是這個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的,但所有的人都像這樣......他們只允許下載一個特定的文件。 任何人都可以幫助我嗎? 非常感謝!

+0

你嘗試過什麼?您是否對您下載的代碼進行了任何修改?你做了什麼改變?什麼工作?什麼沒有?除了尋找可以下載的完整解決方案之外,您是否做過任何研究?只是從互聯網上覆制和粘貼代碼不會讓你走得很遠,有時候你還得自己做一些工作。 – Adrian

+0

@Adrian感謝您的回覆。 正如我所說的,上面的代碼工作正常只下載一個文件作爲它在Servlet中的路徑。在這個例子中,在init()函數中。 我試圖給filePath attribute.example一個字符串的路徑:filepath =「C:// Apache // Application // data //」,但我收到一個錯誤:拒絕訪問。我嘗試了一些其他的東西:使用文件屬性和listFiles方法在我的JSP中創建一個文件夾的內容列表,然後我寫' AdiCrainic

+0

@ user2236267嘗試使用不同的路徑,如* C:\\ external \\ path *。另外,請確保您的用戶有足夠的權限寫入該文件夾。我沒有包含那些信息,因爲我假定你已經知道了。 –

回答

6

由於您正在處理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(""); 
} 
+0

**非常感謝您的回答** 我嘗試了您的代碼,但無法使其工作。 – AdiCrainic

+0

@ user2236267試試看。如果它符合您的需求,請在名稱下方標記檢查以將帖子標記爲答案。 –

+0

我是新來的stackoverflow.it將需要一些時間來與我一起工作。 我試圖給你一個答案,但它告訴我需要15個信譽。我想回復我的新代碼,但它告訴我的評論太大了。 – AdiCrainic

1

你可以做這樣的

 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(); 
} 
0
// 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