javaWeb實現文件上傳與下載 (轉)

文件上傳概述java

實現web開發中的文件上傳功能,需完成以下二步操做:web

web頁面中添加上傳輸入項算法

servlet中讀取上傳文件的數據,並保存到本地硬盤中。編程

如何在web頁面中添加上傳輸入項?瀏覽器

<input type=「file」>標籤用於在web頁面中添加文件上傳輸入項,設置文件上傳輸入項時須注意:緩存

一、必需要設置input輸入項的name屬性,不然瀏覽器將不會發送上傳文件的數據。安全

2、必須把form的enctype屬值設爲multipart/form-data.設置該值後,瀏覽器在上傳文件時,將把文件數據附帶在http請求消息體中,並使用MIME協議對上傳的文件進行描述,以方便接收方對上傳數據進行解析和處理。服務器

文件上傳概述jsp

如何在Servlet中讀取文件上傳數據,並保存到本地硬盤中?函數

Request對象提供了一個getInputStream方法,經過這個方法能夠讀取到客戶端提交過來的數據。但因爲用戶可能會同時上傳多個文件,在servlet端編程直接讀取上傳數據,並分別解析出相應的文件數據是一項很是麻煩的工做,示例。

爲方便用戶處理文件上傳數據,Apache開源組織提供了一個用來處理表單文件上傳的一個開源組件( Commons-fileupload),該組件性能優異,而且其API使用極其簡單,可讓開發人員輕鬆實現web文件上傳功能,所以在web開發中實現文件上傳功能,一般使用Commons-fileupload組件實現。

使用Commons-fileupload組件實現文件上傳,須要導入該組件相應的支撐jar包:Commons-fileupload和commons-io。commons-io不屬於文件上傳組件的開發jar文件,但Commons-fileupload組件從1.1版本開始,它工做時須要commons-io包的支持。

fileupload組件工做流程

核心API—DiskFileItemFactory

DiskFileItemFactory 是建立 FileItem 對象的工廠,這個工廠類經常使用方法:

public void setSizeThreshold(int sizeThreshold):設置內存緩衝區的大小,默認值爲10K。當上傳文件大於緩衝區大小時, fileupload組件將使用臨時文件緩存上傳文件。

public void setRepository(java.io.File repository):指定臨時文件目錄,默認值爲System.getProperty("java.io.tmpdir").

public DiskFileItemFactory(int sizeThreshold, java.io.File repository):構造函數

核心API—ServletFileUpload

ServletFileUpload 負責處理上傳的文件數據,並將表單中每一個輸入項封裝成一個 FileItem 對象中。經常使用方法有:

boolean isMultipartContent(HttpServletRequest request):判斷上傳表單是否爲multipart/form-data類型

List parseRequest(HttpServletRequest request):解析request對象,並把表單中的每個輸入項包裝成一個fileItem對象,並返回一個保存了全部FileItem的list集合。

setFileSizeMax(long fileSizeMax):設置上傳文件的最大值

setSizeMax(long sizeMax):設置上傳文件總量的最大值

setHeaderEncoding(java.lang.String encoding):設置編碼格式

setProgressListener(ProgressListener pListener)

文件上傳案例

實現步驟

1、建立DiskFileItemFactory對象,設置緩衝區大小和臨時文件目錄

2、使用DiskFileItemFactory對象建立ServletFileUpload對象,並設置上傳文件的大小限制。

3、調用ServletFileUpload.parseRequest方法解析request對象,獲得一個保存了全部上傳內容的List對象。

4、對list進行迭代,每迭代一個FileItem對象,調用其isFormField方法判斷是不是上傳文件

爲普通表單字段,則調用getFieldName、getString方法獲得字段名和字段值

爲上傳文件,則調用getInputStream方法獲得數據輸入流,從而讀取上傳數據。

編碼實現文件上傳

上傳文件的處理細節

中文文件亂碼問題

文件名中文亂碼問題,可調用ServletUpLoader的setHeaderEncoding方法,或者設置request的setCharacterEncoding屬性

臨時文件的刪除問題

因爲文件大小超出DiskFileItemFactory.setSizeThreshold方法設置的內存緩衝區的大小時,Commons-fileupload組件將使用臨時文件保存上傳數據,所以在程序結束時,務必調用FileItem.delete方法刪除臨時文件。

Delete方法的調用必須位於流關閉以後,不然會出現文件佔用,而致使刪除失敗的狀況。

文件存放位置

爲保證服務器安全,上傳文件應保存在應用程序的WEB-INF目錄下,或者不受WEB服務器管理的目錄。

爲防止多用戶上傳相同文件名的文件,而致使文件覆蓋的狀況發生,文件上傳程序應保證上傳文件具備惟一文件名。

爲防止單個目錄下文件過多,影響文件讀寫速度,處理上傳文件的程序應根據可能的文件上傳總量,選擇合適的目錄結構生成算法,將上傳文件分散存儲。

 

 

 

文件下載

由於要下載的文件能夠是各類類型的文件,因此要將文件傳送給客戶端,其相應內容應該被當作二進制來處理,因此應該調用 方法返回 ServeltOutputStream對象來向客戶端寫入文件內容。

 

下載案例

遍歷上傳目錄下的全部文件顯示給用戶,並容許用戶完成下載。

(讀取某一個文件夾下的全部的文件,存到集合裏面List,再存到request做用域範圍中)ListFileServelt—(將全部的文件列表顯示)Listfiles.jsp-----DownloaServlet.java

private String id;

private String savename; //上傳文件的名稱,文件的uuid名

private String realName; //上傳文件的真實名稱

private String savepath; //記住文件的位置

private Date uptime; //文件的上傳時間

private String description; //文件的描述

private String username; //上傳人

ListFileServlet

package com.hbsi.servlet;

 

import java.io.File;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.HashMap;

import java.util.Map;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

 

public class ListFileServlet extendsHttpServlet {

 

publicvoid doGet(HttpServletRequest request, HttpServletResponse response)

throwsServletException, IOException {

Stringsavepath = this.getServletContext().getRealPath(

"/WEB-INF/upload");

 

Mapmap = new HashMap();

listFiles(newFile(savepath), map);

request.setAttribute("map",map);

 

request.getRequestDispatcher("/listfile.jsp")

.forward(request,response);

}

 

privatevoid listFiles(File file, Map map) {

 

if(file.isFile()) {

Stringuuidname = file.getName(); // uuid_a_1_3_3.txt

Stringrealname = uuidname.substring(uuidname.indexOf("_") + 1);

 

map.put(uuidname,realname);

 

}else {

File[]files = file.listFiles();

for(File f : files) {

listFiles(f,map);

}

}

}

 

publicvoid doPost(HttpServletRequest request, HttpServletResponse response)

throwsServletException, IOException {

doGet(request,response);

}

 

}

 

DownloadServlet

package com.hbsi.servlet;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.io.PrintWriter;

import java.net.URLEncoder;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

 

public class DownloadServlet extendsHttpServlet {

 

publicvoid doGet(HttpServletRequest request, HttpServletResponse response)

throwsServletException, IOException {

Stringfilename = request.getParameter("filename");

filename= new String(filename.getBytes("iso8859-1"), "utf-8");

System.out.println(filename);

Stringsavepath = this.getFileSavePath(this.getRealName(filename));

Filef = new File(savepath + "\\" + filename);

 

if(!f.exists()) {

request.setAttribute("message","下載的資源不存在");

request.getRequestDispatcher("/message.jsp").forward(request,response);

 

}

 

response.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode(this.getRealName(filename),"UTF-8"));

 

FileInputStreamin = new FileInputStream(f);

byte[]buf = new byte[1024];

intlen = 0;

 

OutputStreamout = response.getOutputStream();

while((len = in.read(buf)) > 0) {

out.write(buf,0, len);

}

in.close();

 

}

 

publicString getFileSavePath(String filename) {

 

intdir1 = filename.hashCode() & 0xf;

intdir2 = (filename.hashCode() >> 4) & 0xf;

Stringsavepath = this.getServletContext().getRealPath("/WEB-INF/upload")+"\\" + dir1 + "\\" + dir2;

 

returnsavepath;

}

 

publicString getRealName(String filename) {

StringrealName = filename.substring(filename.indexOf("_") + 1);

returnrealName;

}

 

publicvoid doPost(HttpServletRequest request, HttpServletResponse response)

throwsServletException, IOException {

doGet(request,response);

}

 

}

原文地址:http://blog.csdn.net/chrp99/article/details/8253036

相關文章
相關標籤/搜索