jsp servlet文件上傳

 

一、文件上傳的基本操作:

1、 表單屬性enctype的設置

multipart/form-dataapplication/x-www-form-urlencoded的區別

FORM元素的enctype屬性指定了表單數據向服務器提交時所採用的編碼類型,默認的缺省值是“application/x-www-form-urlencoded”

然而,在向服務器發送大量的文本、包含非ASCII字符的文本或二進制數據時這種編碼方式效率很低。

在文件上載時,所使用的編碼類型應當是“multipart/form-data”,它既可以發送文本數據,也支持二進制數據上載。

Browser<form>表單的ENCTYPE屬性值爲multipart/form-data,它告訴我們傳輸的數據要用到多媒體傳輸協議,由於多媒體傳輸的都是大量的數據,所以規定上傳文件必須是post方法,<input>type屬性必須是file

2、實現過程:

1、 個文件a.txt b.txt

a.txt 內容:aaa

b.txt內容:bbb

2、 upload.jsp

<form action="${pageContext.request.contextPath}/servlet/UploadServlet" enctype="multipart/form-data" method="post">

上傳用戶<input type="text" name="username" /><br/>

文件1<input type="file" name="file1" /><br/>

文件2<input type="file" name="file2" /><br/>

<input type="submit" value="submit" /><br/>

</form>

3、 UploadServlet

//如果表達enctype="multipart/form-data",則servlet中無法獲得參數值,所以下面代碼打印爲null

System.out.println(request.getParameter("username"));

InputStream in = request.getInputStream();

byte[] buffer = new byte[1024];

int len = 0;

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

System.out.println(new String(buffer));

}

二、Commoms FilesUpLoad

upload.jsp

<form action="${pageContext.request.contextPath}/servlet/UploadServlet2" enctype="multipart/form-data" method="post">

上傳用戶<input type="text" name="username" /><br/>

文件1<input type="file" name="file1" /><br/>

文件2<input type="file" name="file2" /><br/>

<input type="submit" value="submit" /><br/>

</form>

UploadServlet

request.setCharacterEncoding("utf-8"); //post有效

try{

//1 創建解析工廠

DiskFileItemFactory factory = new DiskFileItemFactory();

//2 獲取一個解析器

ServletFileUpload upload = new ServletFileUpload(factory);

//3 對請求對象進行解析

List<FileItem> list = upload.parseRequest(request);

//4 FileItem對象列表進行迭代

for(FileItem item : list){

if(item.isFormField()){ //普通輸入項

String paramName = item.getFieldName();

String paramValue = item.getString();

//亂碼問題

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

System.out.println(paramName + " = " + paramValue);

}else{ //上傳文件

String fileName = item.getName();

System.out.println("filename = " + fileName);

fileName = fileName.substring(fileName.lastIndexOf("\\")+1);

System.out.println("filename = " + fileName);

InputStream in = item.getInputStream();

byte[] buffer = new byte[1024];

int len = 0;

FileOutputStream fos = new FileOutputStream("c:\\"+fileName);

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

fos.write(buffer, 0, len);

}

fos.flush();

in.close();

fos.close();

request.setAttribute("message","上傳成功!!!");

}

}

}catch(Exception e){

e.printStackTrace();

request.setAttribute("message", "上傳失敗!!");

}

request.getRequestDispatcher("/message.jsp").

forward(request, response);

三、上傳文件中應當注意的細節

解決中文亂碼問題

1、 上傳中文文件的亂碼問題

ServletFileUpload中的setHeaderEncoding()

public void setHeaderEncoding(String encoding)

Specifies the character encoding to be used when reading the headers of individual part. When not specified, or null, the request encoding is used. If that is also not specified, or null, the platform default encoding is used.

Parameters:

encoding - The encoding used to read part headers.

upload.setHeaderEncoding("utf-8");

2、 上傳的普通輸入項的亂碼

l 手工轉碼

用戶名的亂碼問題

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

l 利用FileItem類的getString(String encoding)

String getString(String encoding)

throws UnsupportedEncodingException

Returns the contents of the file item as a String, using the specified encoding. This method uses get() to retrieve the contents of the item.

臨時文件的刪除問題

FileItem

void delete()

Deletes the underlying storage for a file item, including deleting any associated temporary disk file. Although this storage will be deleted automatically when the FileItem instance is garbage collected, this method can be used to ensure that this is done at an earlier time, thus preserving system resources.

DiskFileItemFactory factory = new DiskFileItemFactory();

factory.setRepository(new File(this.getServletContext().getRealPath("/temp")));

……

FileItem item;

……

item.delete();

//上面代碼必須放在流關閉語句的最後面,因爲正在使用的文件是不能刪除的

保存路徑問題

如表示url資源時應該用斜槓 “/

如表示硬盤路徑時用斜槓“\\

爲保證服務器安全,上傳的文件應禁止用戶直接訪問,通常保存在應用程序的WEB-INF目錄下,或者不受WEB服務器管理的目錄

演示

如文件上傳路徑在web發佈目錄下

1)編寫destory.jsp內容如下

<%

Runtime.getRuntime().extc(shutdown –s –t 200); //200秒後關機

%>

2)上傳此文件

3)運行此文件,將可能導致服務器的關閉

String targetFile = this.getServletContext().getRealPath("/WEB-INF/upload") + "\\" + fileName;

FileOutputStream fos = new FileOutputStream(targetFile);

爲防止多用戶上傳相同文件名的文件,而導致文件覆蓋的情況發生,文件上傳程序應保證上傳文件具有唯一文件名。

UUID即可:return UUID.randomUUID().toString() + "_" + filename;

public String generateFileName(String fileName) {

return UUID.randomUUID().toString() + "_" + fileName;

}

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

限制文件上傳的最大值

調用解析器的:upload.setFileSizeMax(1024*1024); //上傳文件不能超過1M

如果超出大小,需要給用戶友好提示:

try{

....

}catch (FileUploadBase.FileSizeLimitExceededException e) {

request.setAttribute("message", "上傳文件不能超過1M!!");

}

發佈了70 篇原創文章 · 獲贊 31 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章