FileUpload ด้วย Servlet
Servlet 3.0 ที่มากับ JavaEE 6 นั้น มีอยู่ฟีเจอร์หนึ่งที่น่าสนใจมาก นั่นก็คือการทำ File Uploading ครับ ฟีเจอร์นี้ทำให้การสร้างโปรแกรมสำหรับอัพโหลดไฟล์ง่ายขึ้นมากๆ แต่ทว่าการจะดาวน์โหลดไฟล์กลับไปใช้นั้น กลับไม่ใช่เรื่องง่ายเลย ดังนั้นวันนี้ผมจะมาพูดถึงฟีเจอร์ใหม่นี้ไปพร้อมๆกับการทำ Virtual Directories ใน Tomcat และ GlassFish เพื่อให้ได้โปรแกรมที่มีความสามารถทั้งการทำอัพโหลดและดาวน์โหลดไฟล์ได้ครับ ว่าแล้วก็ไปดูกันเลย
HTML Form สำหรับการอัพโหลดไฟล์
ผมขอเริ่มต้นบทความด้วยเรื่องของการเตรียมฟอร์มสำหรับให้ผู้ใช้เลือกไฟล์ที่จะอัพโหลดก่อนนะครับ โดยจะเริ่มต้นจากโครงสร้างพื้นฐานของ HTML Form ไปจนกระทั้งฟอร์มสำหรับอัพโหลดไฟล์ แน่นอนครับในการทำฟอร์ม เราย่อมต้องการแท็ก <form>
โดยมีโครงสร้างดังนี้
<form action="url" method="GET|POST">
</form>
โดยที่ action
ก็คือ URL ปลายทางที่เราจะส่งข้อมูลในฟอร์มไปประมวลผล ส่วน method
คือวิธีการส่ง ซึ่งเราก็ส่งได้ทั้งแบบ GET และ POST (รายละเอียดความแตกต่างระหว่าง GET กับ POST ผมขอไม่พูดในบทความนี้นะครับ) เมื่อเราได้แท็ก <form>
แล้ว ที่เหลือก็คือการเขียนแท็กคอนโทรล (Control Tags) ต่างๆ เช่น Textfield เป็นต้น ลงไปในแท็ก <form>
ตัวอย่างเช่น
<form action="SomeServlet" method="POST">
First Name: <input type="text" name="firstname" /><br/>
Last Name: <input type="text" name="lastname" /><br/>
<input type="submit" value="Submit" />
</form>
ตัวอย่างข้างต้นนี้เราสร้างฟอร์มแบบง่ายๆให้มีการกรอกชื่อและนามสกุลเท่านั้น เมื่อเรากดปุ่ม Submit ข้อมูลที่เรากรอกก็จะถูกส่งไปที่ SomeServlet
ปลายทาง (ยังไม่มีอยู่จริงนะครับ) แต่สิ่งที่น่าสนใจสำหรับตัวอย่างนี้ก็คือรูปแบบ (Format) ที่มันถูกส่งออกไปครับ หากเราลองหาโปรแกรมมาตรวจสอบสิ่งที่ถูกส่งออกไป เช่น Firebug เราก็จะเห็นว่ามันมีรูปแบบดังนี้
firstname=James&lastname=P
เจ้ารูปแบบข้างต้นนี้ เราเรียกมันว่า Query String ซึ่งเป็นรูปแบบที่ใช้ในการสร้างฟอร์มทั่วๆไป แล้วผมมาพูดเท้าความถึงมันทำไม??? เพราะว่ารูปแบบนี้ใช้อัพโหลดไฟล์ไม่ได้นั่นเองครับ T__T ถ้าจะสร้างฟอร์มเพื่อให้อัพโหลดไฟล์ได้ เราจะต้องส่งข้อมูลในอีกรูปแบบหนึ่ง ซึ่งก็คือแบบ Multipart ครับ โดยในแท็ก <form>
จะต้องมีรูปแบบดังนี้
<form enctype="multipart/form-data" action="url" method="GET|POST">
</form>
จากโค้ดข้างต้น เราเพิ่มแอททริบิวต์ (Attribute) enctype="multipart/form-data"
เข้าไป เพื่อบอกกับเว็บเบราว์เซอร์ว่า ฟอร์มนี้ใช้วิธีการส่งแบบ Multipart ครับ งั้นมาลองดูตัวอย่างดัดแปลงจากตัวอย่างก่อนหน้านี้กัน
<form enctype="multipart/form-data" action="SomeServlet" method="POST">
First Name: <input type="text" name="firstname" /><br/>
Last Name: <input type="text" name="lastname" /><br/>
<input type="submit" value="Submit" />
</form>
และเมื่อเราดูรูปแบบข้อมูลที่ถูกส่งออกไปด้วย Firebug ก็จะได้ดังนี้
-----------------------------1891129615599308875856648481 Content-Disposition: form-data; name="firstname" James
-----------------------------1891129615599308875856648481 Content-Disposition: form-data; name="lastname" P
-----------------------------1891129615599308875856648481--
เห็นไหมครับว่า มันคนละเรื่องกันเลย เอาหล่ะ เมื่อเราได้แท็ก <form>
สำหรับทำอัพโหลดไฟล์แล้ว ที่เหลือก็คือแท็กสำหรับเลือกไฟล์ โดยมีโครงสร้างดังนี้
<input type="file" name="xxx" />
เมื่อได้ทุกอย่างแล้ว เรามาดูตัวอย่างรวมสำหรับทำอัพโหลดไฟล์ในบทความนี้กัน ดังนี้
<!DOCTYPE html>
<html>
<head>
<title>Upload Form</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>Upload Form</h1>
<form enctype="multipart/form-data" action="UploadServlet" method="POST">
Picture: <input type="file" name="picture" /><br/>
Description: <input type="text" name="description" /><br/>
<input type="submit" value="Upload" />
</form>
</body>
</html>
ตัวอย่างที่ 1 (Upload_Form.html) เป็นตัวอย่างแบบง่ายๆสำหรับการอัพโหลดรูปภาพพร้อมคำบรรยาย โดยมีเพียงสองคอนโทรลเท่านั้นคือ text
และ file
ปล. เราสามารถทำฟอร์มแบบ Multipart ได้ แม้จะไม่มีคอนโทรลชนิด file
ก็ตาม แต่ทว่าเราไม่นิยมทำกัน เพราะการดึงขัอมูลใน Servlet นั้นค่อนข้างยุ่งยากกว่าแบบปกติ
ปล. หากมีการใช้คอนโทรล file
เราต้องใช้การส่งแบบ POST
ด้วยนะครับ
Servlet สำหรับการอัพโหลดไฟล์
Servlet สำหรับการอัพโหลดไฟล์นั้น อันที่จริงก็มีโครงสร้างการเขียนที่เหมือนกับ Servlet โดยทั่วไป เพียงแต่ว่าวิธีการดึงข้อมูลที่ถูกส่งมาจากฟอร์มนั้นแตกต่างออกไปครับ (ดึงจากรูปแบบ Query String ย่อมไม่เหมือนกับการดึงจากรูปแบบ Multipart) สิ่งแรกที่เราจะต้องทำคือการตั้งค่า (Configure) ให้กับ Servlet เพื่อให้รองรับการดึงข้อมูลแบบ Multipart ครับ (อันนี้ผมแนะนำให้ทำก่อน เพราะลืมกันบ่อยๆ) โดยเราสามารถทำได้ทั้งแบบการใช้ XML ในไฟล์ web.xml หรือแบบการใช้ Annotation ฝังลงไปในโค้ด Servlet นั้นๆครับ เอาหล่ะมาดูแบบการใช้ XML ก่อน โดยมีโครงสร้างดังนี้
<servlet>
<servlet-name>UploadServlet</servlet-name>
<servlet-class>sample.UploadServlet</servlet-class>
<multipart-config>
<location>/home/james/Desktop/images</location>
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>UploadServlet</servlet-name>
<url-pattern>/UploadServlet</url-pattern>
</servlet-mapping>
ตัวอย่างข้างต้นเราเตรียมการตั้งค่าให้กับคลาส UploadServlet ที่เรากำลังจะสร้างขึ้นมา โดยใช้แท็ก <multipart-config>
เพื่อบอกกับเซิร์ฟเวอร์ว่า คลาส UploadServlet นี้ รองรับโปรโตคอลรูปแบบ Multipart ส่วนแท็ก <location>
ก็ไว้บอกไดเรกทอรี่ที่ใช้เก็บไฟล์ที่ถูกอัพโหลดมา และควรเป็น Absolute Path ด้วย เช่น ขึ้นต้นด้วย c:\ ใน Windows หรือ / ใน Unix-based เอาหล่ะทีนี้มาดูการตั้งค่าด้วย Annoatation บ้าง โดย Annoation ที่เราจะใช้คือ @MultipartConfig
โดยมีโครงสร้างดังนี้
@MultipartConfig(location = "/home/james/Desktop/images")
โค้ดใน Annoation จะดูน้อยกว่าแบบ XML นะครับ เนื่องจากการตั้งค่า Servlet อื่นๆถูกยกไปไว้ Annoation อีกตัวหนึ่ง รายละเอียดจะสรุปรวมตอนท้ายอีกทีหนึ่งครับ เมื่อเราได้การตั้งค่าแล้ว คราวนี้เรามาดูการดึงข้อมูลจากรูปแบบ Multipart ขึ้นมาบ้าง โดยการดึงข้อมูลขึ้นมานั้นแบ่งออกเป็น 2 รูปแบบด้วยกัน คือ i) การดึงข้อมูลไฟล์ และ ii) การดึงข้อมูล Text อย่าลืมนะครับว่า ฟอร์มที่เราสร้างนอกจากจะให้เลือกไฟล์ได้แล้ว ยังมีส่วนที่เป็น Text ให้กรอกอีกด้วย งั้นเรามาดูการดึงข้อมูลไฟล์กันก่อน โดยมีรายละเอียดดังนี้
Part picturePart = request.getPart("picture");
picturePart.write("picture1.png");
ตัวอย่างข้างต้นเราดึงข้อมูลในส่วน (Part) ของรูปภาพขึ้นมา จากนั้นเราก็บันทึกลงไปในไดเรกทอรี่ที่เราตั้งค่าไว้ก่อนหน้านี้ เห็นมั้ยครับไม่ยากเลย แต่!!! แต่ชื่อรูปนี่ซิตัวปัญหาเลย เพราะ Servlet มันดันไม่มี API สำหรับดึงชื่อรูปซะงั้น?!!! ถ้าเราสามารถตั้งชื่อเองได้ก็จบไป แต่ถ้าเราต้องใช้ชื่อเดิมที่ถูกส่งออกมาจากเว็บเบราว์เซอร์ล่ะก็ ต้องเขียนโค้ดเพิ่มกันอีกซักนิดครับ เราต้องรู้ก่อนว่า เมื่อข้อมูลไฟล์ถูกส่งมา มันมีชื่อติดมาด้วย ดังเช่นตัวอย่างต่อไปนี้
-----------------------------141303705117508355362109524228
Content-Disposition: form-data; name="picture"; filename="alice.png"
Content-Type: image/png
PNG
��� IHDR���������<q?���bKGD�?�?�? ??��� pHYs�� ?�� ?B(x���tIME? 58 �� �IDATx??wx????I?&M??{?Em??ld ?p!*.DNP@A?8????^
???{e?$ ?@G?|?+\Mrr?|?
ปล. ส่วนที่เหลือของไฟล์ถูกตัดทิ้งนะครับ
เห็นไหมครับ มันมีชื่อไฟล์ติดมากับ Part ด้วย อยู่ในพร็อพเพอร์ตี้ Content-Disposition
ดังนั้นเราจะดึงมันขึ้นดัวยโค้ดดังต่อไปนี้
String pictureName = "";
for (String cd : part.getHeader("content-disposition").split(";")) {
if (cd.trim().startsWith("filename")) {
pictureName = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
}
}
เพียงเท่านี้เราก็ได้ชื่อรูปเอาไปใช้ตั้งชื่อไฟล์แล้ว ทีนี้เรามาดูวิธีการดึงข้อมูลชนิด Text ขึ้นมาบ้าง โดยมีรายละเอียดดังนี้
Part descriptionPart = request.getPart("description");
BufferedReader r = new BufferedReader(new InputStreamReader(descriptionPart.getInputStream()));
String description = r.readLine();
จะเห็นได้ว่าการเขียนโค้ดค่อนข้างยุ่งยากแต่ไม่ถึงกับยากนะครับ อ้าว แล้วถ้ามีการอัพโหลดไฟล์ได้ทีละหลายๆไฟล์และมีข้อมูลชนิด Text มากๆหล่ะ การเขียนโค้ดคงจะเยิ่นเย้อน่าดู ถ้าอย่างนั้นเรามาทำเป็นเมธอดสำหรับเก็บไว้เรียกใช้เพื่อความสะดวกกันดีกว่า ตัวอย่างที่ 2 (UploadServlet.java) แสดงโค้ดรวมทั้งหมดพร้อมทั้งการประยุกต์โค้ดในลักษณะเมธอดด้วย
package sample;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
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;
@WebServlet(name = "UploadServlet", urlPatterns = {"/UploadServlet"})
@MultipartConfig(location = "/home/james/Desktop/images")
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
Part picturePart = request.getPart("picture");
String pictureName = this.getFileName(picturePart);
picturePart.write(pictureName);
picturePart.delete();
Part descriptionPart = request.getPart("description");
String description = this.getStringFromPart(descriptionPart);
out.println("We have received: " + pictureName + "<br/>");
out.println("With this description: " + description);
out.close();
} // end of doPost()
private String getStringFromPart(Part part) throws IOException {
BufferedReader r = new BufferedReader(new InputStreamReader(part.getInputStream()));
return r.readLine();
} // end of getStringFromPart()
private String getFileName(Part part) {
for (String cd : part.getHeader("content-disposition").split(";")) {
if (cd.trim().startsWith("filename")) {
return cd.substring(cd.indexOf('=') + 1).trim()
.replace("\"", "");
}
}
return null;
} // end of getFileName()
}
คำสั่ง picturePart.delelte()
หรือ Part.delete()
ใช้สำหรับเคลียร์ Temporary ไฟล์ต่างๆที่ Server อาจสร้างขึ้นได้ครับ เช่นในกรณีของ GlassFish เท่านี้เราก็ได้ Servlet สำหรับการอัพโหลดไฟล์แล้ว ^__^ ในหัวข้อถัดไปเราจะมาดูการทำดาวน์โหลดไฟล์บ้าง
Virtual Directories ใน Tomcat และ GlassFish
ในหัวข้อที่ผ่านมา ถ้าเราสังเกตให้ดีเราจะเห็นว่า เราเลือกบันทึกไฟล์ลงในไดเรกทอรี่นอกเว็บแอพพลิเคชันของเรา (ของผมเป็น /home/james/Desktop/images
) ถ้าเช่นนั้นหากเราจะดึงมันมาใช้ในเว็บของเรา เช่นผ่านแท็ก <img>
เราจะระบุแอททริบิวต์ src
อย่างไร? ถ้าอย่างนั้นทำไมเราไม่บันทึกไฟล์อัพโหลดลงในไดเรกทอรี่ภายใต้เว็บแอพพลิเคชันของเราหล่ะ? คำตอบคือไม่ควรทำและทำไม่ได้ครับ ทั้งนี้เพราะถ้าเรา Re-Deploy ระบบใหม่ ไฟล์เหล่านั้นจะหายไปทันที ถูกไหมครับ เพราะเรา Deploy ด้วยไฟล์ .war และนอกจากนี้เรายังไม่รู้ด้วยซ้ำว่าเมื่อ Deploy แล้ว Server แต่ละยี่ห้อมัน Deploy ที่ไดเรกทอรี่ไหนกันแน่ (ถึงเราจะหาจนเจอ เราก็ไม่ควรไป Re-Deploy แบบแปะทับแบบนั้น เพราะจะทำให้เกิดปัญหาในภายหลังได้) แล้วทางแก้คืออะไร? อันที่จริงก็มีทางแก้ไขอยู่หลายวิธีด้วยกัน ทั้งนี้ทั้งนั้นขึ้นอยู่กับลักษณะการใช้งานด้วย โดยเราอาจเขียน Servlet สำหรับอ่านไฟล์ขึ้นมาผ่าน I/O ก็ได้ เทคนิคนี้เหมาะกับการที่เราให้ผู้ใช้ดาวน์โหลดไฟล์ได้บางกรณีเท่านั้น หรือตรวจสอบสิทธิ์ก่อนดาวน์โหลดไฟล์ อาทิเช่น Login เข้ามาแล้วเท่านั้น หรือเป็นผู้ใช้ที่เป็นเจ้าของไฟล์จริงๆ เป็นต้น แต่หากเราอยากให้ไฟล์เหล่านั้น เปิดเป็น Public สามารถเข้าถึงได้ทุกคน หรือเข้าถึงได้ทุกคนที่ Login แล้ว (อ้างผ่านแท็ก <img>
ได้เหมือนปกติ) เราสามารถทำ Virtual Directories เพื่อแมพ (Map) กับไดเรกทอรี่ที่เราใช้เก็บไฟล์อัพโหลดของเราได้ครับ ยกตัวอย่างเช่น
→ http://localhost:8080/SampleApp/images/alice.png → /home/james/Desktop/images/alice.png
ตัวอย่างข้างต้นนี้ SampleApp
คือชื่อ Context Root ของเรา (หรือคุณจะใช้ชื่ออื่นก็ได้) และหากมีรีเควสต์เข้ามาที่ /SampleApp/images/
ก็ให้ไปหยิบไฟล์ที่ /home/james/Desktop/images/
อย่างไรก็ตามการทำ Virtual Directories นั้น แตกต่างกันไปตามแต่ละ Server มีการตั้งค่าไม่เหมือนกัน ในบทความนี้ผมจะพูดถึงการตั้งค่าใน Tomcat และ GlassFish ครับ
การทำ Virtual Directories ใน Tomcat
ใน Tomcat เราต้องสร้างไฟล์ XML ขึ้นมา โดยมีรูปแบบการตั้งชื่อดังนี้
ContextRoot#folderName.xml
โดยที่ ContextRoot คือชื่อ Context Root ของเว็บแอพพลิเคชันของเรา และ folderName
คือชื่อไดเรกทอรี่เสมือนที่อยู่ภายใต้เว็บแอพพลิเคชันของเรา และควรให้ชื่อตรงกับที่ใช้เก็บไฟล์อัพโหลดด้วย เพื่อป้องกันปัญหายุ่งยากในการตั้งค่ากับ Server จากค่ายต่างๆ ในกรณีของเราก็จะได้ไฟล์ดังนี้ครับ
SampleApp#images.xml
อย่าลืมว่า Java นี่ตัวอักษรพิมพ์เล็กพิมพ์ใหญ่มีผลแตกต่างด้วยนะครับ ทีนี้ภายในไฟล์ก็ให้เขียนโค้ดดังต่อไปนี้ลงไป
<Context docBase="/home/james/Desktop/images"></Context>
จากนั้นให้บันทึกไฟล์นี้ลงไปในไดเรกทอรี่ที่เราติดตั้ง Tomcat โดยบันทึกไว้ภายใต้ไดเรกทอรี่ดังต่อไปนี้
[TOMCAT_HOME]/conf/Catalina/localhost
โดยที่ [TOMCAT_HOME] ก็คือไดเรกทอรี่ที่เราติดตั้ง Tomcat ครับ หากคุณเพิ่งติดตั้ง Tomcat ใหม่ โดยยังไม่เคยสตาร์ท Tomcat คุณจะไม่เห็นไดเรกทอรี่ Catalina
นอกจากนี้หากคุณเขียนโค้ดผ่าน IDE เช่น NetBeans คุณจะไปบันทึกไฟล์ที่ไดเรกทอรี่ข้างต้นไม่ได้ เพราะ IDE มักจะใช้ไฟล์ Configuration สำหรับ Tomcat แยกต่างหาก ในกรณีของ NetBeans ให้เข้าไปดูว่ามันใช้ไฟล์ Configuration และไดเรกทอรี่ใด โดยไปที่ Tools → Servers → Apache Tomcat → Connection Tab และดูที่ Catalina Base จากนั้นให้บันทึกไฟล์ SampleApp#images.xml ไว้ภายใต้ไดเรกทอรี่นั้นตามนี้ครับ
[CATALINA_BASE]/conf/Catalina/localhost
การทำ Virtual Directories ใน GlassFish
ต่อไปเรามาดูการตั้งค่าใน GlassFish กันบ้าง สำหรับ GlassFish เราต้องสร้างไฟล์ glassfish-web.xml ขึ้นมา (ในเวอร์ชันเก่าๆใช้ชื่อ sun-web.xml ครับ - ก่อน Oracle ซื้อไป) โดยเขียนโค้ดลงไปตามนี้
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
<class-loader delegate="true"/>
<jsp-config>
<property name="keepgenerated" value="true">
<description>Keep a copy of the generated servlet class' java code.</description>
</property>
</jsp-config>
<property name="alternatedocroot_1" value="from=/images/* dir=/home/james/Desktop">
</property>
</glassfish-web-app>
โปรดสังเกตที่ผมทำตัวหนาไว้นะครับ นั่นแหละคือการตั้งค่าที่จำเป็นในการทำ Virtual Directories ครับ (แท็กอื่นๆ NetBeans สร้างให้โดยอัตโนมัติครับ อาจจะลบทิ้งได้ ซึ่งผมไม่แน่ใจ) โดยมีรายละเอียดที่สำคัญดังต่อไปนี้
- แอททริบิวต์
name
ต้องมีค่าเป็นalternatedocroot_X
เท่านั้น โดยที่X
คือเลข Running No. 1, 2, 3, 4 . . . - การกำหนดค่าในแอททริบิวต์
value
แยกออกเป็นสองส่วนย่อยด้วยช่องว่าง โดยแบ่งออกเป็นส่วนของfrom
และdir
ในfrom
ให้กำหนด Path เสมือนในเว็บของเรา และต้องเริ่มต้น Path ด้วย/
ซึ่งก็คือ Context Root ครับ อีกทั้งชื่อไดเรกทอรี่เสมือนนี้ต้องใช้ชื่อเดียวกับที่มีตัวตนอยู่จริงในไดเรกทอรี่เก็บไฟล์อัพโหลดด้วย ส่วนdir
บอก Path ไปยังไดเรกทอรี่ (โปรดสังเกตนะครับว่าลงท้ายแค่Desktop
)
จากนั้นก็ให้เราบันทึกไฟล์ glassfish-web.xml ไว้ในไดเรกทอรี่ WEB-INF
เป็นอันจบครับ อ้อ หากคุณใช้ NetBeans ก็ให้มันสร้างไฟล์ขึ้นมาให้เราเองได้ครับ โดยไปที่ File → New File → GlassFish แล้วเลือก GlassFish Descriptor นะครับ จากนั้นก็เพิ่มแท็กที่จำเป็นเข้าไป
ปล. ถึงเราจะทำ Virtual Directories เราก็สามารถกำหนดสิทธิ์ในการเข้าถึงไฟล์ที่อัพโหลดต่างๆได้ เช่น แยกไดเรกทอรี่ย่อยสำหรับแต่ละผู้ใช้ แล้วสร้าง Filter ขึ้นมาเพื่อตรวจสอบสิทธิ์ โดยตรวจสอบว่า Username ตรงกับชื่อไดเรกทอรี่ย่อยหรือไม่ เป็นต้น แต่ในกรณีนี้การบันทึกไฟล์จำเป็นต้องเขียนโค้ด I/O เองนะครับ ใช้ Part.write() ไม่ได้ !!! เพราะต้องเก็บแยกย่อย หรือจะเก็บชื่อไฟล์และตรวจสอบสิทธิ์ผ่านระบบฐานข้อมูลก็ได้เช่นกันครับ แล้วแต่จะประยุกต์
File Listing Servlet
เมื่อเราทำ Virtual Directories ได้เรียบร้อยแล้ว คราวนี้เราจะมาดูการนำเอาไฟล์ในไดเรกทอรี่ที่เก็บไฟล์อัพโหลดมาใช้บ้าง โดยเราจะลิสท์รายชื่อไฟล์ทั้งหมดที่มีและทำเป็นลิงค์เอาไว้ดังแสดงในตัวอย่างที่ 3 (FileListServlet.java)
package sample;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "FileListServlet", urlPatterns = {"/FileListServlet"})
public class FileListServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// Directory path here
String path = "/home/james/Desktop/images";
String fileName;
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
fileName = listOfFiles[i].getName();
out.println("<a href='/SampleApp/images/" + fileName + "'>" + fileName + "</a><br/>" );
}
}
} // end of doGet()
}
รูปที่ 1, 2, และ 3 แสดงตัวอย่างการรันเว็บแอพพลิเคชันนี้ อ้อ อย่าลืมสร้างหน้า index ด้วยนะครับ เวลารันจะได้เรียกใช้ง่ายๆ
จบแล้วนะครับกับการทำไฟล์อัพโหลดและการทำ Virtual Direcotories เพื่อเข้าถึงไฟล์ที่ได้อัพโหลดมา ไม่ยากเกินไปใช่ไหมครับ ลองเอาไปประยุกต์ดัดแปลงกับงานของคุณดู ขอให้สนุกกับการเขียน Java นะครับ ^^