Servlet 檔案處理
Servlet 接收檔案、儲存檔案會牽涉到不少基礎的檔案處理,包括 InputStream、OutputStream、byte...
Servlet 接收檔案、儲存檔案會牽涉到不少基礎的檔案處理,包括 InputStream、OutputStream、byte … 就不要多說了,說多了嚇人而已,直接開始吧!
InputStream、OutputStream
在用 Java 做檔案處理的時候,一定會碰到的就是 InputStream、OutputStream 我們在 OPENHOME InputStream、OutputStream 可以看到非常完整的講解 同時我也覺得他們的水管圖超棒, 真的是我看過對 Java 的 Input / Output 最清晰的解釋了! ( 簡直是 做超好的教學 讓別人沒東西寫呀~ )
這邊就不對 Input / Output 多做解釋了! 我們馬上來看看 Servlet 中接受檔案是怎麽個一回事吧!
Servlet Post 方法處理
上次 Servlet 接收參數 的最後,有偷偷寫了一小段 doPost 的處理,但由於什麼都沒有學過,我們就在這邊從頭來學過吧!
doPost
先來個上傳檔案表單
<!DOCTYPE html>
<html>
<body>
<form
action="http://localhost:8080/tomcat-hello/file-upload"
method="POST"
enctype="multipart/form-data"
>
<input type="file" name="file">
<button type="submit">送出</button>
</form>
</body>
</html>
Servlet 物件
@MultipartConfig() // 這個是為了要使用 getPart() 方法一定要加的哦!
@WebServlet(
name = "FileUpload",
urlPatterns = {"/file-upload"}, // 等等要把這串敲在網頁根目錄之後
loadOnStartup = 1
)
public class FileUpload extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Part filePart = req.getPart("file");
String filename = filePart.getSubmittedFileName(); // 取得檔名
InputStream in = filePart.getInputStream(); // 取得 InputStream
OutputStream out = new FileOutputStream("/your/path/" + filename); // 定義 OutputStram 輸出位置
byte[] buffer = new byte[1024];
int length = -1;
while ((length = in.read(buffer)) != -1) {
out.write(buffer, 0, length); // 檔案寫入
}
}
}
getPart() 方法接受一個字串參數,字串就是我們 form 表單的 name 阿記得如果要使用 getPart() 方法,Servlet 一定要有標註 @MultipartConfig 如果對 @MultipartConfig 有興趣的話,我有單獨寫一篇關於註解的整理,請大家多多照料了~
其實我們也可以一次上傳多個檔案 再來個上傳表單看看
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form
action="http://localhost:8080/tomcat-hello/parts-upload"
method="POST"
enctype="multipart/form-data"
>
<input type="file" name="file">
<input type="file" name="file">
<input type="file" name="file">
<input type="file" name="file">
<button type="submit">送出</button>
</form>
</body>
</html>
Servlet 物件
@MultipartConfig(
// 當檔案處理中、或檔案大小超過 fileSizeThreshold 定義時的暫存目錄
// 另外 Part 的 .write() 方法也是預設會把檔案寫進這個目錄
location = "/your/path",
fileSizeThreshold = 1024 * 1024 * 20, // 定義檔案暫存門檻
maxFileSize = 1024 * 1024 * 20, // 允許單個檔案最大大小;當上傳檔案大小超過定義會丟出 exception (IllegalStateException)
maxRequestSize = 1024 * 1024 * 20 // 允許整個 multipart/form-data 要求最大大小;當上傳檔案大小超過定義會丟出 exception (IllegalStateException)
)
@WebServlet(
name = "PartsUpload",
urlPatterns = {"/parts-upload"}, // 等等要把這串敲在網頁根目錄之後
loadOnStartup = 1
)
public class PartsUpload extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Collection<Part> partCollection = req.getParts(); // 把所有傳入的 Part 都抓出來
for (Part part : partCollection) {
String partName = part.getName(); // form 表單的欄位
if (Objects.equals(partName, "file")) {
// write() 方法會去看 @MultipartConfig 定義的 location 位置寫檔案
part.write(part.getSubmittedFileName());
}
}
}
}
這次的 Servlet 物件我多用了很多 @MultipartConfig 的相關屬性,目的是希望讀者們可以多看看。 其實現在 Servlet 單純檔案的上傳,是不需要碰到恐怖的 Input / Output 的, 只要定義了 location 屬性 再呼叫 Part 的 .write() 方法,就會自己寫到 location 定義的資料夾位置底下了!
另外 Parts() 方法會回傳一個 Collection ,Collection裡面包裹的是傳過來的每個 Part 物件,不論是一段字還是檔案,都會囊括在裡面 那這邊的範例,我們直接用 for 迴圈把 Collection 迭代出來, 再透過 getName() 方法確認 form 表單傳過來的 name 是否為 "file" 確認過後直接使用 part 的 write() 方法,進行檔案的寫入動作!
今天就到這邊吧!之後,我們來練習包成一個 zip 吧!