ภาพรวมการอัปโหลดไฟล์
ในการรับรู้ฟังก์ชั่น การอัปโหลดไฟล์ ในการพัฒนาเว็บคุณต้องทำตาม สองขั้นตอน ต่อไปนี้:
เพิ่มการอัปโหลดอินพุตไปยังหน้าเว็บ
อ่านข้อมูลไฟล์ที่อัปโหลดใน servlet และบันทึกลงในฮาร์ดดิสก์ท้องถิ่น
จะเพิ่มรายการอินพุตอัปโหลดไปยังหน้าเว็บได้อย่างไร?
แท็ก <อินพุต type = "ไฟล์"> ใช้เพื่อเพิ่มไฟล์อัปโหลดไฟล์อินพุตไฟล์ไปยังหน้าเว็บ คุณต้องใส่ใจเมื่อตั้งค่าไฟล์อัปโหลดรายการอินพุต:
1. แอตทริบิวต์ชื่อของรายการอินพุตอินพุตจะต้องตั้งค่ามิฉะนั้นเบราว์เซอร์จะไม่ส่งข้อมูลไฟล์ที่อัปโหลด
2. ค่า Enctype ของแบบฟอร์มจะต้องตั้งค่าเป็น multipart/form-data หลังจากตั้งค่าค่านี้เมื่อเบราว์เซอร์อัปโหลดไฟล์มันจะแนบข้อมูลไฟล์กับตัวข้อความคำขอ HTTP และใช้โปรโตคอล MIME เพื่ออธิบายไฟล์ที่อัปโหลดเพื่ออำนวยความสะดวกให้กับตัวรับสัญญาณเพื่อแยกวิเคราะห์และประมวลผลข้อมูลที่อัปโหลด
ภาพรวมการอัปโหลดไฟล์
วิธีอ่านข้อมูลการอัปโหลดไฟล์ใน Servlet และบันทึกลงในฮาร์ดดิสก์ในพื้นที่
วัตถุคำขอมีวิธีการ GetInputStream ซึ่งสามารถอ่านข้อมูลที่ส่งข้อมูลโดยไคลเอนต์ อย่างไรก็ตามเนื่องจากผู้ใช้อาจอัปโหลดหลายไฟล์ในเวลาเดียวกันจึงเป็นงานที่ลำบากมากในการอ่านข้อมูลการอัปโหลดโดยตรงบนด้าน servlet และแยกวิเคราะห์ข้อมูลไฟล์ที่เกี่ยวข้องแยกกันตัวอย่าง
เพื่ออำนวยความสะดวกให้ผู้ใช้สามารถประมวลผลข้อมูลการอัปโหลดไฟล์ Apache Open Source Organization จัดเตรียมส่วนประกอบโอเพ่นซอร์ส (Commons-FilePileLoad) ที่ใช้ในการประมวลผลการอัปโหลดไฟล์แบบฟอร์ม ส่วนประกอบนี้มีประสิทธิภาพที่ยอดเยี่ยมและ API นั้นใช้งานง่ายมากช่วยให้นักพัฒนาสามารถใช้ฟังก์ชั่นการอัปโหลดเว็บไฟล์ได้อย่างง่ายดาย ดังนั้นฟังก์ชั่นการอัปโหลดไฟล์มักจะถูกนำไปใช้ในการพัฒนาเว็บซึ่งมักจะใช้งานโดยใช้คอมโพเนนต์คอมมอนส์-ฟิลด์อัปโหลด
ใช้คอมโพเนนต์คอมมอนส์-ฟิลด์อัปโหลดเพื่อใช้การอัปโหลดไฟล์และคุณจำเป็นต้องนำเข้าแพ็คเกจ jar สนับสนุนที่เกี่ยวข้องสำหรับส่วนประกอบนี้: Commons-FilePileLoad และ Commons-IO Commons-iO ไม่ได้อยู่ในไฟล์ JAR Development สำหรับส่วนประกอบการอัปโหลดไฟล์ แต่ส่วนประกอบ Commons-Fileupload เริ่มต้นด้วยเวอร์ชัน 1.1 และต้องได้รับการสนับสนุนจากแพ็คเกจ Commons-IO เมื่อใช้งานได้
fileupload Workflow ส่วนประกอบ
Core API - DiskFileItemFactory
DiskFileItemFactory เป็นโรงงานที่สร้างวัตถุ FileItem วิธีการทั่วไปสำหรับคลาสโรงงานนี้:
โมฆะสาธารณะ setsizethreshold (int sizethreshold): ตั้งค่าขนาดของบัฟเฟอร์หน่วยความจำค่าเริ่มต้นคือ 10k เมื่อไฟล์อัปโหลดมีขนาดใหญ่กว่าขนาดบัฟเฟอร์ส่วนประกอบ fileupload จะอัปโหลดไฟล์โดยใช้แคชไฟล์ชั่วคราว
โมฆะสาธารณะ setRepository (ที่เก็บ java.io.file): ระบุไดเรกทอรีไฟล์ชั่วคราวค่าเริ่มต้นคือ System.getProperty ("java.io.tmpdir")
สาธารณะ diskfileitemfactory (int sizethreshold, java.io.file repository): constructor
Core API - ServletFilePload
ServletFileUpload รับผิดชอบในการประมวลผลข้อมูลไฟล์ที่อัปโหลดและห่อหุ้มแต่ละรายการอินพุตในแบบฟอร์มลงในวัตถุ FileItem วิธีการทั่วไปคือ:
บูลีน ismultipartcontent (คำขอ httpservletrequest): กำหนดว่าแบบฟอร์มที่อัปโหลดเป็นแบบหลายส่วน/แบบฟอร์ม-ข้อมูล
รายการ parserequest (คำขอ httpservletrequest): แยกวิเคราะห์วัตถุคำขอห่อแต่ละรายการอินพุตในแบบฟอร์มลงในวัตถุ FileItem และส่งคืนคอลเลกชันรายการที่บันทึกไฟล์ทั้งหมด
SetFilesizEmax (Long FilesizEmax): ตั้งค่าสูงสุดของไฟล์ที่อัปโหลด
SetSizeMax (Long Sizemax): ตั้งค่าสูงสุดของจำนวนไฟล์ที่อัปโหลดทั้งหมด
Setheaderencoding (java.lang.string encoding): ตั้งค่ารูปแบบการเข้ารหัส
SetProgressListener (ProgressListener Plistener)
กรณีอัปโหลดไฟล์
ขั้นตอนการดำเนินการ
1. สร้างวัตถุ DiskFileItemFactory ตั้งค่าขนาดบัฟเฟอร์และไดเรกทอรีไฟล์ชั่วคราว 2. ใช้วัตถุ DiskFileItemFactory เพื่อสร้างวัตถุ ServletFilePilePload และตั้งค่าขีด จำกัด ขนาดสำหรับการอัปโหลดไฟล์
3. วิธีการเรียกใช้ servletfileupload.parserequest เพื่อแยกวิเคราะห์วัตถุคำขอและรับวัตถุรายการที่บันทึกเนื้อหาที่อัปโหลดทั้งหมด
4. วนซ้ำรายการ แต่ละคนวนซ้ำวัตถุ FileItem และเรียกใช้เมธอด iSformfield เพื่อตรวจสอบว่าเป็นไฟล์ที่อัปโหลดหรือไม่
มันเป็นฟิลด์ฟอร์มปกติจากนั้นเรียกใช้วิธี getfieldName และ getString เพื่อรับชื่อฟิลด์และค่าฟิลด์
ในการอัปโหลดไฟล์วิธี getInputStream จะเรียกว่าเพื่อรับสตรีมอินพุตข้อมูลดังนั้นจึงอ่านข้อมูลที่อัปโหลด
การเข้ารหัสเพื่อใช้การอัปโหลดไฟล์
การประมวลผลรายละเอียดของการอัปโหลดไฟล์
ปัญหาที่อ่านไม่ออกไฟล์ภาษาจีน
ปัญหาของชื่อไฟล์ภาษาจีนที่อ่านไม่ออกคุณสามารถเรียกวิธีการ setheaderencoding ของ servletuploader หรือตั้งค่าคุณสมบัติ setcharacterencoding ของคำขอ
ปัญหาการลบไฟล์ชั่วคราว
เนื่องจากขนาดไฟล์เกินขนาดของบัฟเฟอร์หน่วยความจำที่ตั้งค่าโดย DiskFileItemFactory.SetSizEthReshold วิธีการส่วนประกอบคอมมอนส์-ฟิลด์อัปโหลดจะใช้ไฟล์ชั่วคราวเพื่อบันทึกข้อมูลที่อัปโหลด ดังนั้นในตอนท้ายของโปรแกรมให้แน่ใจว่าได้เรียกใช้วิธี fileitem.delete เพื่อลบไฟล์ชั่วคราว
การโทรไปยังวิธีการลบจะต้องเป็นหลังจากสตรีมปิดมิฉะนั้นการใช้งานไฟล์จะเกิดขึ้นส่งผลให้เกิดความล้มเหลวในการลบ
ตำแหน่งที่เก็บไฟล์
เพื่อให้แน่ใจว่าความปลอดภัยของเซิร์ฟเวอร์ไฟล์ที่อัปโหลดควรถูกบันทึกไว้ในไดเรกทอรี Web-Inf ของแอปพลิเคชันหรือไดเรกทอรีที่ไม่ได้จัดการโดยเว็บเซิร์ฟเวอร์
เพื่อป้องกันไม่ให้ผู้ใช้หลายคนอัพโหลดไฟล์ด้วยชื่อไฟล์เดียวกันส่งผลให้ไฟล์ทับเอกสารการอัปโหลดไฟล์ควรตรวจสอบให้แน่ใจว่าไฟล์ที่อัปโหลดมีชื่อไฟล์ที่ไม่ซ้ำกัน
เพื่อป้องกันไฟล์มากเกินไปในไดเรกทอรีเดียวและส่งผลกระทบต่อความเร็วในการอ่านและเขียนไฟล์โปรแกรมที่จัดการไฟล์ที่อัปโหลดควรเลือกอัลกอริทึมการสร้างโครงสร้างไดเรกทอรีที่เหมาะสมตามจำนวนไฟล์ที่เป็นไปได้ทั้งหมดที่อัปโหลดและจัดเก็บไฟล์ที่อัปโหลดในลักษณะที่กระจัดกระจาย
ดาวน์โหลดไฟล์
เนื่องจากไฟล์ที่จะดาวน์โหลดอาจเป็นประเภทต่าง ๆ ไฟล์จะต้องถ่ายโอนไปยังไคลเอนต์และเนื้อหาที่เกี่ยวข้องควรถูกประมวลผลเป็นไบนารีดังนั้นวิธีการควรเรียกใช้เพื่อส่งคืนวัตถุ ServelToutputStream เพื่อเขียนเนื้อหาไฟล์ไปยังไคลเอนต์
ดาวน์โหลดเคส
วนซ้ำผ่านไฟล์ทั้งหมดในไดเรกทอรีการอัปโหลดและแสดงไปยังผู้ใช้และอนุญาตให้ผู้ใช้ดาวน์โหลดได้
(อ่านไฟล์ทั้งหมดในโฟลเดอร์ที่แน่นอนบันทึกไว้ในรายการในคอลเลกชันจากนั้นบันทึกไว้ในขอบเขตของคำขอ) ListFilesERVLT-(แสดงรายการไฟล์ทั้งหมด) listfiles.jsp ---- downloaservlet.javaprivate id id; string private String savename; // ชื่อของไฟล์อัปโหลดชื่อ UUID ของไฟล์สตริงส่วนตัว realName; // ชื่อจริงของไฟล์อัปโหลดสตริงส่วนตัวบันทึก SavePath; // จำตำแหน่งของไฟล์วันที่ส่วนตัวของไฟล์ // เวลาอัปโหลดของไฟล์สตริงส่วนตัวคำอธิบาย; // คำอธิบายของชื่อผู้ใช้สตริงส่วนตัวไฟล์; // uploader listfileservletpackage com.hbsi.servlet; นำเข้า java.io.file; นำเข้า java.io.ioexception; นำเข้า java.io.printwriter; นำเข้า java.util.hashmap; นำเข้า Java.util.map javax.servlet.http.httpservlet; importjavax.servlet.http.httpservletrequest; importjavax.servlet.http.httpservletresters; การตอบสนอง) THROWSSERVLETEXception, iOException {stringsavePath = this.getServletContext (). getRealPath ("/web-inf/upload"); mapmap = new hashmap (); listfiles (newfile (savepath) แผนที่); request.setAttribute ("แผนที่", แผนที่); request.getRequestDispatcher ("/listfile.jsp"). forward (คำขอ, การตอบสนอง);} privateVoid listfiles (ไฟล์ไฟล์แผนที่) {ถ้า (file.isfile ()) // UUID_A_1_3_3.TXTSTRINGREALNAME = UUIDNAME.SUBSTRING (UUIDNAME.INDEXOF ("_") + 1); map.put (uuidName, realname);} elle {ไฟล์ [] ไฟล์ = ไฟล์ dopost (httpservletrequest Request, httpservletResponse การตอบสนอง) throwsservletexception, ioexception {doget (คำขอ, การตอบสนอง);}} downloadservletpackage com.hbsi.servlet; นำเข้า java.io.file; java.io.printwriter; นำเข้า java.net.urlencoder; นำเข้า Javax.servlet.servletexception; นำเข้า Javax.servlet.http.httpservlet; importjavax.servlet.http.httpservletRequest; Extendshttpservlet {publicvoid doGet (คำขอ httpservletrequest, การตอบสนอง httpservletResponse) พุ่งเข้าหา ServleTexception, iOexception {stringfilename = request.getParameter ("filename"); filename = สตริงใหม่ "UTF-8"); System.out.println (ชื่อไฟล์); stringsavePath = this.getFilesavePath (this.getRealName (ชื่อไฟล์)); filef = ไฟล์ใหม่ (บันทึก + "//" + ชื่อไฟล์) ถ้า (! f.exists ()) มีอยู่ "); request.getRequestDispatcher ("/message.jsp "). forward (คำขอ, การตอบสนอง);} response.Setheader (" เนื้อหา-การจัดสรร "," สิ่งที่แนบมา; filename = "+ urlencoder.encode ไบต์ [1024]; intlen = 0; outputStreamout = response.getOutputStream (); ในขณะที่ ((len = in.read (buf))> 0) {out.write (buf, 0, len);} in.close (); (filename.hashCode () >> 4) & 0xf; stringsavePath = this.getServletContext (). getRealPath ("/web-inf/upload") + "//" + dir1 + "//" + dir2; returnsavepath; filename.substring (filename.indexof ("_") + 1); returnRealName;} publicVoid dopost (คำขอ httpservletrequest, httpservletresponse response) throwsservletexception, ioexception