Servlet 3.0 加入了上傳機制
之前寫過的cos套件也可以拿來比對
除了本篇介紹,另外可參考良葛格的介紹
<form action="uploadTest" method="post" enctype="multipart/form-data">
<p>選擇檔案:</p><input type="file" name="file1" value="" /><br />
<p>選擇檔案:</p><input type="file" name="file2" value="" /><br />
<input type="submit" name="upload" value="upload" />
</form>
Servlet 3.0新增了part介面來方便檔案上傳的處理
整體相當簡單易用
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
@MultipartConfig(location="C:/") //for web container,and set file destination
@WebServlet("/uploadTest")
public class uploadTest extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException{
req.setCharacterEncoding("UTF-8");
for(Part part : req.getParts()) { //get collections of part objects
if("application/octet-stream".equals(part.getContentType())) {
String header = part.getHeader("Content-Disposition");
String filename = header.substring(
header.indexOf("filename=\"") + 10, header.lastIndexOf("\""));
long maxsize = 5 * 1024 * 1024; //max size = 5 MB
if(! "".equals(filename) && part.getSize() < maxsize){
part.write(filename);
}
}
}
}
}
程式碼簡短又很明瞭
MultipartConfig annotation可以設定 Servlet 如何處理上傳檔案
少了這一行會讓 container 無法使用 part
如果沒有填入設定的屬性,就會啟用預設值;可以設定的屬性有
fileSizeThreshould - 上傳檔案大小超過設定值時會先寫入暫存檔案,預設值0
location - 字串設定檔案寫入的目錄,預設為空字串
maxFileSize - 限制上傳檔案大小,預設值 -1L 為不限制檔案大小
maxRequestSize - 限制 multipart/form-data 請求的數目,預設值 -1L 為不限制
屬性設定很方便,但要小心對應的錯誤處理
而表單裡面的所有 input 欄位都會被包成 part 物件
假如表單裡面只有一個上傳欄位的話可以用 req.getPart(fieldName) 這樣取得
若有多個上傳欄位則使用 .getParts() 處理
"application/octet-stream".equals(part.getContentType()) 這個條件過濾 type="file" 的 input 欄位
要取得檔案名稱的話則用 part.getHeader("Content-Disposition")
每個檔案的 Content-Disposition header長這樣 form-data; name="file1"; filename="a.txt"
從這裡就可以擷取字串取得 file name
part 的 getSize() 是整個機制裡面讓我最喜歡的部分,可以在上傳前取得檔案大小
之前使用 cos 套件時沒辦法做到這樣,總覺得很浪費資源
最後一切需求都確認好之後就用 wirte() 方法寫入檔案到目的地的目錄
目標目錄如果不用MultipartConfig annotation設定,也可以寫在 web.xml 中
...
<servlet>
<servlet-name>uploadTest</servlet-name>
<servlet-class>tw.vencs.uploadTest</servlet-class>
<multipart-config>
<location>c:/</location>
</multipart-config>
</servlet>
...
part的其他較常用的方法還有
getName() - 取得 input 欄位的 attribute
getInputStream() - 取得檔案的 inputStream,可以搭配 outputStream 實作檔案寫入
不過 part 已經幫我們包好了 write(),不需要再實作這個功能就是了
之前寫過的cos套件也可以拿來比對
除了本篇介紹,另外可參考良葛格的介紹
使用時對於提供上傳的form表單有些前置需求,如下
上傳的頁面demo.jsp==================
<!-- action指向處理後續的頁面/Servlet 實作上傳功能時method只能用post
enctype沒指定的話會用預設值application/x-www-form-urlencoded
使用上傳功能時則設定為multipart/form-data-->
<form action="uploadTest" method="post" enctype="multipart/form-data">
<p>選擇檔案:</p><input type="file" name="file1" value="" /><br />
<p>選擇檔案:</p><input type="file" name="file2" value="" /><br />
<input type="submit" name="upload" value="upload" />
</form>
Servlet 3.0新增了part介面來方便檔案上傳的處理
整體相當簡單易用
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
@MultipartConfig(location="C:/") //for web container,and set file destination
@WebServlet("/uploadTest")
public class uploadTest extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException{
req.setCharacterEncoding("UTF-8");
for(Part part : req.getParts()) { //get collections of part objects
if("application/octet-stream".equals(part.getContentType())) {
String header = part.getHeader("Content-Disposition");
String filename = header.substring(
header.indexOf("filename=\"") + 10, header.lastIndexOf("\""));
long maxsize = 5 * 1024 * 1024; //max size = 5 MB
if(! "".equals(filename) && part.getSize() < maxsize){
part.write(filename);
}
}
}
}
}
程式碼簡短又很明瞭
MultipartConfig annotation可以設定 Servlet 如何處理上傳檔案
少了這一行會讓 container 無法使用 part
如果沒有填入設定的屬性,就會啟用預設值;可以設定的屬性有
fileSizeThreshould - 上傳檔案大小超過設定值時會先寫入暫存檔案,預設值0
location - 字串設定檔案寫入的目錄,預設為空字串
maxFileSize - 限制上傳檔案大小,預設值 -1L 為不限制檔案大小
maxRequestSize - 限制 multipart/form-data 請求的數目,預設值 -1L 為不限制
屬性設定很方便,但要小心對應的錯誤處理
而表單裡面的所有 input 欄位都會被包成 part 物件
假如表單裡面只有一個上傳欄位的話可以用 req.getPart(fieldName) 這樣取得
若有多個上傳欄位則使用 .getParts() 處理
"application/octet-stream".equals(part.getContentType()) 這個條件過濾 type="file" 的 input 欄位
要取得檔案名稱的話則用 part.getHeader("Content-Disposition")
每個檔案的 Content-Disposition header長這樣 form-data; name="file1"; filename="a.txt"
從這裡就可以擷取字串取得 file name
part 的 getSize() 是整個機制裡面讓我最喜歡的部分,可以在上傳前取得檔案大小
之前使用 cos 套件時沒辦法做到這樣,總覺得很浪費資源
最後一切需求都確認好之後就用 wirte() 方法寫入檔案到目的地的目錄
目標目錄如果不用MultipartConfig annotation設定,也可以寫在 web.xml 中
...
<servlet>
<servlet-name>uploadTest</servlet-name>
<servlet-class>tw.vencs.uploadTest</servlet-class>
<multipart-config>
<location>c:/</location>
</multipart-config>
</servlet>
...
part的其他較常用的方法還有
getName() - 取得 input 欄位的 attribute
getInputStream() - 取得檔案的 inputStream,可以搭配 outputStream 實作檔案寫入
不過 part 已經幫我們包好了 write(),不需要再實作這個功能就是了
請問:
回覆刪除如果要去取得 input type="text" name="title" 之類的值,要如何取得呢?
指在Java中嗎? 那就是 request.getParameter("title");
刪除如果對這方面不清楚,建議可以多了解HTML的表單資訊傳送原理