上傳
兩個步驟:
-
用戶在頁面中選擇要上傳的檔案,然后將請求提交到Servlet
-
Servlet收到請求,決議用戶上傳的檔案,然后將檔案存盤到服務器
上傳檔案表單
<form action="Servlet" method="post" enctype="multipart/form-data"> <input type="file" name="file" /><br /><br /> <input type="submit" value="上傳" /> </form>
注意:
-
表單的method屬性必須為post
-
表單的enctype屬性必須為multipart/form-data
-
上傳檔案的控制元件是intput,type屬性為file
注意:Servelet
- 當enctype="multipart/form-data" 時,再使用getParamter()獲取到內容永遠為空,
- 需要引入決議請求中的引數和檔案,這個工具就是commons-fileupload,
commons-fileupload
它的作用就是可以從request物件中決議出,用戶發送的請求引數和上傳檔案的流,
commons-fileupload包依賴commons-io,兩個包需要同時匯入,
核心類:
-
DiskFileItemFactory
-
工廠類,用于創建ServletFileUpload,設定快取等
-
該類一般直接使用構造器直接創建實體
-
方法:
-
public void setSizeThreshold(int sizeThreshold):用于設定快取檔案的大小(默認值10kb)
-
public void setRepository(File repository):用于設定快取檔案位置(默認系統快取目錄)
-
-
-
ServletFileUpload
-
該類用于決議request物件從而獲取用戶發送的請求引數(包括普通引數和檔案引數)
-
該類需要呼叫有參構造器創建實體,構造器中需要一個DiskFileItemFactory作為引數
-
方法:
-
public List<FileItem> parseRequest(HttpServletRequest request):決議request物件,獲取請求引數,回傳的是一個List,List中保存的是一個FileItem物件,一個物件代表一個請求引數,
-
public void setFileSizeMax(long fileSizeMax):設定單個檔案的大小限制,單位為B,如果上傳檔案超出限制,會在parseRequest()拋出例外FileSizeLimitExceededException,
-
public void setSizeMax(long sizeMax):限制請求內容的總大小,單位為B,如果上傳檔案超出限制,會在parseRequest()拋出例外SizeLimitExceededException,
-
-
-
FileItem
-
該類用于封裝用戶發送的引數和檔案,也就是用戶發送來的資訊將會被封裝成一個FileItem物件,我們通過該物件獲取請求引數或上傳檔案的資訊,
-
該類不用我們手動創建,由ServletFileItem決議request后回傳,
-
方法:
-
String getFieldName():獲取表單項的名字,也就是input當中的name屬性的值,
-
String getName():獲取上傳的檔案名,普通的請求引數為null,
-
String getString(String encoding):獲取內容,encoding引數需要指定一個字符集,
① 若為檔案,將檔案的流轉換為字串,
② 若為請求引數,則獲取請求引數的value,
-
boolean isFormField():判斷當前的FileItem封裝的是普通請求引數,還是一個檔案,
① 如果為普通引數回傳:true
② 如果為檔案引數回傳:false
-
String getContentType():獲取上傳檔案的MIME型別
-
long getSize():獲取內容的大小
-
write():將檔案上傳到服務器
-
//創建工廠類 DiskFileItemFactory factory = new DiskFileItemFactory(); //創建請求決議器 ServletFileUpload fileUpload = new ServletFileUpload(factory); //設定上傳單個檔案的的大小 fileUpload.setFileSizeMax(1024*1024*3); //設定上傳總檔案的大小 fileUpload.setSizeMax(1024*1024*3*10); //設定回應內容的編碼 response.setContentType("text/html;charset=utf-8"); try { //決議請求資訊,獲取FileItem的集合 List<FileItem> items = fileUpload.parseRequest(request); //遍歷集合 for (FileItem fileItem : items) { //如果是普通的表單項 if(fileItem.isFormField()){ //獲取引數名 String fieldName = fileItem.getFieldName(); //獲取引數值 String value = https://www.cnblogs.com/Open-ing/p/fileItem.getString("utf-8"); System.out.println(fieldName+" = "+value); //如果是檔案表單項 }else{ //獲取檔案名 String fileName = fileItem.getName(); //獲取上傳路徑 String realPath = getServletContext().getRealPath("/WEB-INF/upload"); //檢查upload檔案夾是否存在,如果不存在則創建 File f = new File(realPath); if(!f.exists()){ f.mkdir(); }; //為避免重名生成一個uuid作為檔案名的前綴 String prefix = UUID.randomUUID().toString().replace("-", ""); //將檔案寫入到服務器中 fileItem.write(new File(realPath+"/"+prefix+"_"+fileName)); //清除檔案快取 fileItem.delete(); }
} } catch (Exception e) { if(e instanceof SizeLimitExceededException){ //檔案總大小超出限制 response.getWriter().print("上傳檔案的總大小不能超過30M"); }else if(e instanceof FileSizeLimitExceededException){ //單個檔案大小超出限制 response.getWriter().print("上傳單個檔案的大小不能超過3M"); } } response.getWriter().print("上傳成功");
下載
下載檔案的關鍵點:
-
服務器以一個流的形式將檔案發送給瀏覽器,
-
發送流的同時還需要設定幾個回應頭,來告訴瀏覽器下載的資訊,
-
具體回應頭如下:
-
Content-Type
-
下載檔案的MIME型別
-
可以通過servletContext. getMimeType(String file)獲取
-
也可以直接手動指定
-
使用response.setContentType(String type);
-
回應頭樣式:Content-Type: audio/mpeg
-
-
Content-Disposition
-
下載檔案的名字,主要作用是提供一個默認的用戶名
-
通過response.setHeader("Content-Disposition", disposition)設定
-
回應頭樣式:Content-Disposition: attachment; filename=xxx.mp3
-
-
Content-Length
-
下載檔案的長度,用于設定檔案的長處(不必須)
-
通過response. setContentLength(int len)設定,
-
設定后樣式:Content-Length: 3140995
-
-
-
-
接下來需要以輸入流的形式讀入硬碟上的檔案
-
FileInputStream is = new FileInputStream(file);
-
這個流就是我們一會要發送給瀏覽器的內容
-
-
通過response獲取一個輸出流,并將檔案(輸入流)通過該流發送給瀏覽器
-
獲取輸出流:ServletOutputStream out = response.getOutputStream();
-
通過輸出流向瀏覽器發送檔案(不要忘了關閉輸入流)
-
步驟演示
以下步驟都是在同一個Servlet的doGet()方法中撰寫的
1.獲取檔案的流:
String realPath = getServletContext().getRealPath("/WEB-INF/mp3/中國話.mp3");
//獲取檔案的File物件
File file = new File(realPath);
//獲取檔案的輸入流
FileInputStream in = new FileInputStream(file);
2.獲取頭資訊:
//獲取檔案的MIME資訊 String contentType = getServletContext().getMimeType(realPath); //設定下載檔案的名字 String filename = "zhongguohua.mp3"; //創建Content-Disposition資訊 String disposition = "attachment; filename="+ filename ; //獲取檔案長度 long size = file.length();
3.設定頭資訊
//設定Content-Type response.setContentType(contentType); //設定Content-Disposition response.setHeader("Content-Disposition", disposition); //設定檔案長度 response.setContentLength((int)size);
4.發送檔案
//通過response獲取輸出流,用于向瀏覽器輸出內容 ServletOutputStream out = response.getOutputStream(); //將檔案輸入流通過輸出流輸出 byte[] b = new byte[1024]; int len = 0; while((len=is.read(b))> 0){ out.write(b, 0, len); } //最后不要忘記關閉輸入流,輸出流由Tomcat自己處理,我們不用手動關閉 is.close();
亂碼
中文檔案名會出現亂碼問題,解決此問題的方法很簡單,在獲取檔案名之后為檔案名進行編碼:
filename = java.net.URLEncoder.encode(filename,"utf-8");
火狐瀏覽器比較特殊需要特殊處理一下,
1.先要獲取客戶端資訊(通過獲取請求頭中的User-Agent資訊)
String ua = request.getHeader("User-Agent");
2.然后判斷瀏覽器版本,做不同的處理
//判斷客戶端是否為火狐 if(ua.contains("Firefox")){ //若為火狐使用BASE64編碼 filename = "=?utf-8?B?"+new BASE64Encoder().encode(filename.getBytes("utf-8"))+"?="; }else{ //否則使用UTF-8 filename = URLEncoder.encode(filename,"utf-8"); }
String string = new String("你好.jpg".getBytes("gbk"), "iso8859-1");
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/83621.html
標籤:Html/Css
