-創建jsp頁面
創建一個包含上傳文件表單的jsp頁面:
<body>
<h1>文件上傳</h1>
<form action="<c:url value='/UploadServlet' />" method="post" enctype="multipart/form-data">
用戶名:<input type="text" name="username" /><br/>
文 件:<input type="file" name="filename"><br/>
<input type="submit" value="上傳" />
</form>
</body>
需要注意的是form默認的編碼格式爲application/x-www-form-urlencoded,不能用於上傳文件。在此,我們需要將他修改爲multipart/form-data
-創建響應表單請求的UploadServlet
在獲取文件的上傳時,我們不能再通過簡單的request.getAttribute()方法去獲取表單內容了,因爲他的請求體發生了改變,我們可以通過HttpWatch這樣的工具去查看請求體。我們可以通過Apache提供的開源組件commons-fileupload.jar(他以來commons-io.jar)來簡化我們獲取表單信息的步驟。
在文件上傳中需要注意一下幾個問題:
1.文件必須保存到WEB-INF下!
2.文件名稱相關問題,有些瀏覽器會提交文件絕對路徑,我們需要切割。
3.目錄打散,分散文件的分佈,避免將所有文件放在一個目錄下。
4.上傳文件的大小限制。
5.緩存大小與臨時目錄。這個默認爲10K,目錄爲“java.io.tmpdir”對應的目錄,具體可以在DiskFileItemFactory中設置。
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
DiskFileItemFactory factory = new DiskFileItemFactory(); //獲取工廠
ServletFileUpload sfu = new ServletFileUpload(factory); //獲取解析器
sfu.setFileSizeMax(10 * 1024); //限制單個文件的大小不得超過10K
sfu.setSizeMax(1024 * 1024); //限制請求的所有數據大小不得超過1M
try {
List<FileItem> listFileItem = sfu.parseRequest(request);//獲取表單項列表
//文件保存目錄,上傳文件存放於WEB-INF目錄下,使瀏覽器不可直接訪問
String root = this.getServletContext().getRealPath("/WEB-INF/files/");
FileItem fileItem1 = listFileItem.get(0);
System.out.println(fileItem1.getFieldName() + ":" + fileItem1.getString("utf-8"));
FileItem fileItem2 = listFileItem.get(1);
//System.out.println("Content-Type:" + fileItem2.getContentType());
//System.out.println("Size:" + fileItem2.getSize());
//System.out.println("FileName:" + fileItem2.getName());
String fileName = fileItem2.getName();
//當文件名稱是絕對路徑時,我們需要截取文件名部分
int index = fileName.lastIndexOf("\\");
if(index != -1){
fileName = fileName.substring(index + 1);
}
//文件名重名問題,uuid_fileName
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
System.out.println(uuid);
String saveName = uuid + "_" + fileName; // 文件保存名字,避免同名文件的衝突
//目錄打散-哈希打散,使用文件名哈希值的十六進制的前兩位
int hashCode = fileName.hashCode();
String hex = Integer.toHexString(hashCode).toUpperCase();
File dirFile = new File(root, hex.charAt(0) + "/" + hex.charAt(1));
//創建目錄鏈,自動生成該鏈中不存在的目錄
dirFile.mkdirs();
File destFile = new File(dirFile, saveName);
//寫入文件
fileItem2.write(destFile);
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}