文件上傳
-
什麼是文件上傳
將本地磁盤文件通過IO寫入到服務器的過程
-
文件上傳的技術
Servlet3.0
JSPSmartUpload
FileUpload
(這個是通用的技術,不像前面兩個需要對應引擎的支持,依託於環境)- 框架(其實框架中的文件上傳技術就是
FileUpload
技術的封裝)
-
文件上傳的三要素
-
表單的提交方式必須爲
POST
-
表單中需要有文件上傳表單項,必須有name屬性
<input type="file" name="upload">
-
表單的
enctype
屬性的值必須爲multipart/form-data
- 如果沒有設置
enctype
屬性,那麼在請求中對應的upload
只能獲取到文件的名字
在請求頭中(只有表單提交的請求中才有
content-Type
)
在請求體中
-
如果在form屬性中設置了
enctype="multipart/form-data"
在請求頭中
在請求體中(在火狐瀏覽器中才能看到)
- 如果沒有設置
-
FileUpload
-
使用
fileUpload
組件首先需要引入兩個jar包:commons-fileUpload.jar
commons-io.jar
-
編碼問題
-
文件名亂碼(防止文件路徑中的中文亂碼)
使用
servletFileUpload.setHeaderEncoding("UTF-8");
(通用方法,因爲上傳文件不一定是在servlet中)或者request.setCharacterEncoding("UTF-8")
都可以。(原理:雖然在表單頁面是以utf-8
的編碼提交的中文,但是在FileUpload
組件中默認是用ISO-8859-1
來解碼,編碼和解碼的標準都不一樣,自然會出現亂碼) -
表單內容亂碼
使用
getString("utf-8")
即可,也就是在獲取內容時,就可以設置編碼。
-
-
如果表單中設置了
enctype="multipart/form-data"
,那麼將不能用request.getParameter()
來獲得請求參數的值。必須先獲得每個FileItem
部分,再通過它的方法來獲取。
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1、創建磁盤文件項工廠類對象
// 不傳入參數,使用默認的緩存區大小(10kb)和默認的臨時文件存放的位置
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
// 2、創建核心解析類對象
ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
// 處理文件路徑中(文件名)爲中文出現亂碼的情況
fileUpload.setHeaderEncoding("utf-8");
try {
// 3、解析請求對象,將請求分成幾個部分(FileItem)
List<FileItem> list = fileUpload.parseRequest(request);
// 4、遍歷集合獲得每個部分的對象
for (FileItem fileItem : list) {
// 判斷是否是普通表單項,是返回true,不是返回false
if (fileItem.isFormField()) {
// 獲得普通項的參數名
String name = fileItem.getFieldName();
// 獲得普通項的參數值,傳入解碼參數值的編碼,不傳默認是"ISO-8859-1"
String value = fileItem.getString("UTF-8");
} else {// 是文件上傳項
// 獲得文件上傳項的參數名
String name = fileItem.getFieldName();
// 獲得文件上傳項的文件名
String fileName = fileItem.getName();
// 獲得文件上傳項的文件輸入流
InputStream is = fileItem.getInputStream();
//生成唯一的文件名
String exName=fileName.substring(fileName.lastIndexOf("."));
String uuid=UUID.randomUUID().toString().replace("-","");
String uuidFileName=uuid+exName;
// 獲得在服務器中保存這些上傳文件的磁盤絕對路徑(物理路徑)
String path = this.getServletContext().getRealPath("/upload") + "\\" + uuidFileName;
OutputStream os = new FileOutputStream(new File(path));
int len = 0;
byte[] b = new byte[1024];
// 從文件的輸入流中讀取,再寫到服務器中指定的文件裏
while ((len = is.read(b)) != -1) {
os.write(b, 0, len);
}
os.close();
is.close();
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}