1. 程式人生 > >java—servlet實現檔案下載功能

java—servlet實現檔案下載功能

最近在學javaweb技術,利用所學知識做了一個簡單的專案,在伺服器上實現給使用者下載檔案的功能。自動列出資料夾下的檔案提供下載,支援中文檔名。

結果圖


       其中使用了tomcat來部署伺服器,程式碼中應用了少許EL表示式和JSTL標籤,使用了jsp和servlet,當然還有java和http的基礎知識,但是個人覺得重點是http的Content-Disposition頭資訊和Content-type頭資訊在servlet中下載方面的應用,詳見DownloadPageServlet.java原始碼。

講解的比較詳細,但是程式碼貌似不是java的。

   關於Content-type,可以參考線上工具:

   本專案包含一個jsp檔案,用來展示可下載的檔案列表,顯示為超連結,使用者點選即可下載對應檔案。一個javabean,用來儲存可供使用者下載的檔案和檔名。一個servlet,用來提供下載功能。

   Jsp中超連結的實現方式:指向servlet,在網址後面附加引數,servlet可以根據附加引數知道使用者想要下載哪個檔案。

   結構圖


備註1.本人覺得專案結構並不是很好,還望指教。

2.不知道有沒有方便的專用作圖軟體。

如果讀者對上面2個問題有所瞭解的話還望指導。

   在myeclipse中新建一個web程式,新增下述3個檔案,修改一下包名錯誤,在web.xml中配飾上servlet,訪問jsp檔案,應該就可以看到效果了。

DownloadPageServlet.java原始碼

package com.ima.downLoad;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ima.downLoad.util.FilesBean;

public class DownloadPageServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		
		//理論上傳來的網址是 ?後面跟一個數字表示第n個檔案
		String str = request.getQueryString();
		//如果沒有引數則什麼也不做
		if (str != null) {
			FilesBean bean = new FilesBean();
			File f = null;
			try {
				f = bean.getFiles().get(Integer.valueOf(str) - 1);
			} catch (Exception e) {
				// 沒有對應檔案會丟擲陣列越界異常
				e.printStackTrace();
				return;
			}
			System.out.println("DownloadPageServlet:使用者欲得到的資源是  " + f.getName());
			if (f != null) {
				BufferedInputStream bis = null;
				try {
					// 得到檔案輸入流
					bis = new BufferedInputStream(new FileInputStream(f));
					// !!!
					//設定http頭資訊為檔案下載     
					//!!!保證在下一步之前,我曾經寫在下一步之後,不能正常實現功能  
					response.setContentType("application/octet-stream");
					
					response.addHeader(
							"Content-Disposition",
							"attachment;filename="
									+ URLEncoder.encode(f.getName(), "UTF-8"));
					// 得到應答輸出流,並寫入
					ServletOutputStream os = response.getOutputStream();
					byte[] buf = new byte[1024 * 8];
					int len = -1;
					while ((len = bis.read(buf)) != -1) {
						os.write(buf, 0, len);
					}
				} catch (Exception e) {
				} finally {
					if (bis != null)
						bis.close();
				}
			}
		}
	}

}

FileBean.java原始碼
package com.ima.downLoad.util;

import java.io.File;
import java.util.ArrayList;

/**
 * 獲得指定資料夾下的檔案,生成list,對外提供檔案list和檔名list
 * @author tor
 *
 */
public class FilesBean {
	private String targetDir = "E:/imaLearn/8組共享/";
	//下面2個list應該是同步的
	//檔案list,用來讀取
	ArrayList<File> files = new ArrayList<File>();
	//檔名list,用來顯示
	ArrayList<String> fileNames = new ArrayList<String>();

	public FilesBean() {
		init();
	}

	public ArrayList<String> getFileNames() {
		return fileNames;
	}

	/**
	 * 初始化函式,每次改變相關引數需要呼叫
	 */
	private void init() {
		File[] fileList = new File(targetDir).listFiles();
		for (File file : fileList) {
			if (file.canRead() && file.canWrite() && !file.isHidden()) {
				files.add(file);
				fileNames.add(file.getName());
			}
		}
	}

	

	public String getTargetDir() {
		return targetDir;
	}

	public void setTargetDir(String targetDir) {
		this.targetDir = targetDir;
		init();//重新初始化
	}

	public ArrayList<File> getFiles() {
		return files;
	}

}
showFiles.jsp原始碼
<%@page import="com.ima.downLoad.util.FilesBean"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib  uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!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=UTF-8">
<title>下載資源頁面</title>
</head>
<body>
<h3>8組共享</h3><br/>
<%request.setAttribute("fileBean", new FilesBean()); %>
<c:forEach items="${fileBean.fileNames }" var="file" varStatus="state">
<a target="_blank" href="${pageContext.request.contextPath }/servlet/DownloadPageServlet?${state.count }">${file }</a><br/>
</c:forEach>


</body>
</html>