Servlet 3.0改進的API 實現檔案上傳
阿新 • • 發佈:2019-01-27
1、Servlet 3.0 對檔案上傳的支援
Servlet 3.0 改進了部分API,使得java web 的開發進一步得到簡化。
其中兩個較大的改進是:
- HttpServletRequest 增加了對檔案上傳的支援
- ServletContext 允許通過程式設計的方式動態註冊Servlet、Filter
HttpServletRequest 提供瞭如下兩個方法來處理檔案上傳 :
- Part getPart(String name) : 根據檔案上傳域name屬性來獲取上傳檔案。
- Collection< Part > getParts() :獲取所有的檔案上傳域。
官方文件對這兩個方法的說明為:
上面兩個方法的返回值都涉及一個API :Part ;每個Part物件對應於一個檔案上傳域,該物件提供了大量方法來訪問上傳的檔案,如檔案型別、大小等。並提供了一個write(String name)將檔案寫入伺服器硬碟。
上傳檔案表單 :
為了向伺服器上傳檔案,需要在表單裡使用 < input type=”file” name=”xxx” …./>檔案域,這個檔案域會在HTML頁面生成一個單行文字框和一個用於“瀏覽檔案”的button。除此之外,表單必須設定enctype屬性
enctype屬性指定的是表單資料的編碼方式,該屬性有如下三個值:
- application/x-www-form-urlencoded :這是預設的編碼方式,他只處理表單域裡的value屬性值,採用這種編碼方式的表單會將表單域的值處理成URL編碼方式
- multipart/form-data : 這種方式會以二進位制流的方式來處理表單資料,這種編碼方式會把 檔案域指定檔案的內容 (並不是原檔案,而是檔案內容)也封裝到請求引數裡
- text/plain : 這種編碼方式當表單的action 屬性為 mailto:URL 時比較方便,主要用於直接通過表單傳送郵件
如果將enctype設定為 application/x-www-form-urlencoded ,或者不設定enctype屬性,提交表單時只會傳送檔案域文字框裡的字串,也就是瀏覽者所選擇檔案的絕對路徑。這對伺服器來說沒多大用處,畢竟伺服器又無法訪問客戶機的檔案系統。
Servlet實現檔案上傳程式碼:
使用Servlet實現檔案上傳非常簡單,不需要commons-fileupload 等工具。注意匯入servlet-api.jar
表單示例:
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="submit">
</form>
Servlet示例:
/**@MultipartConfig
* 不指定location屬性時,在IDEA環境下,part.write(fileName);上傳檔案預設儲存到以下地址
* C:\Users\Windward\.IntelliJIdea2017.1\system\tomcat\index_jsp_upLoad\work\Catalina\localhost\ROOT下
* 指定location屬性,需要手動建立資料夾
* 1.相對路徑時:如 location = "/uploadFiles"
* 儲存地址為:E:\apache-tomcat-8.0.24\work\Catalina\localhost\upLoad_war_exploded\uploadFiles
* 2.絕對路徑時:如 location = "F:\\uploadFiles"
* 儲存至絕對路徑下,如 F:\uploadFiles下
*
*/
@javax.servlet.annotation.MultipartConfig(location = "F:\\uploadFiles")
@javax.servlet.annotation.WebServlet(name = "upload",urlPatterns={"/upload"})
public class UploadServlet extends javax.servlet.http.HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
//設定請求的編碼方式
request.setCharacterEncoding("utf-8");
//設定響應內容,與編碼
response.setContentType("text/html;charset=utf-8");
//獲取輸出流,輸出到客戶端瀏覽器
PrintWriter out = response.getWriter();
//獲取檔案上傳域 "file"域,Part物件封裝了獲取的檔案
Part part = request.getPart("file");
//獲取檔案型別
String fileType = part.getContentType();
//獲取檔案大小
Long size= part.getSize();
//獲取檔案上傳域的所有headerName
Collection<String> headerNames = part.getHeaderNames();
//獲取包含原始檔名的字串
String fileNameInfo = part.getHeader("content-disposition");
//提取上傳檔案的原始檔名
String fileName = fileNameInfo.substring(fileNameInfo.indexOf("filename=")+10,
fileNameInfo.length()-1);
//將檔案寫入伺服器硬碟,存入的檔名為fileName(write的引數),
// 路徑為@MultipartConfig(location = "/uploadFiles")location屬性值
part.write(fileName);
out.println("<html>");
out.println("<body>");
out.print("檔名:"+fileName+"<br/>");
out.print("檔案型別:"+fileType+"<br/>");
out.print("檔案大小(byte):"+size+"<br/>");
//遍歷列印檔案上傳域的所有 HeaderName-Value
for (String headerName: headerNames ) {
out.print("------------------------------------------------------------------"+"<br/>");
out.print("headerName :"+headerName+"<br/>");
//輸出headerName對應的value值
out.print("value:"+part.getHeader(headerName) +"<br/>");
out.print("------------------------------------------------------------------"+"<br/>");
}
out.println("</body>");
out.println("</html>");
out.close();
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
doPost(request,response);
}
}