ในการพัฒนาระบบเว็บแอปพลิเคชันฟังก์ชั่นการอัปโหลดและดาวน์โหลดไฟล์เป็นฟังก์ชั่นที่ใช้กันทั่วไป วันนี้มาพูดคุยเกี่ยวกับการใช้งานฟังก์ชั่นการอัปโหลดและดาวน์โหลดไฟล์ใน Javaweb
สำหรับการอัปโหลดไฟล์เบราว์เซอร์จะส่งไฟล์ไปยังเซิร์ฟเวอร์ในรูปแบบของสตรีมระหว่างกระบวนการอัปโหลด มันเป็นปัญหามากขึ้นหากคุณใช้ Servlet โดยตรงเพื่อรับสตรีมอินพุตของไฟล์ที่อัปโหลดแล้วแยกวิเคราะห์พารามิเตอร์คำขอในนั้น ดังนั้นโดยทั่วไปจึงถูกเลือกให้ใช้ Common-FilePilePload ซึ่งเป็นส่วนประกอบอัพโหลดไฟล์ของเครื่องมือ Open Apache Open แพ็คเกจ JAR ของส่วนประกอบการอัปโหลดแบบสามัญทั่วไปสามารถดาวน์โหลดได้บนเว็บไซต์อย่างเป็นทางการของ Apache หรือสามารถพบได้ภายใต้โฟลเดอร์ LIB ของ Struts ฟังก์ชั่นของการอัปโหลด Struts ขึ้นอยู่กับการใช้งานนี้ Common-Fileupload ขึ้นอยู่กับแพ็คเกจ Common-IO ดังนั้นคุณต้องดาวน์โหลดแพ็คเกจนี้ด้วย
1. การก่อสร้างสภาพแวดล้อมการพัฒนา
สร้างโครงการ FileUploadandDownload และเพิ่มแพ็คเกจ JAR ที่เกี่ยวข้องของ Commons-FileUp
2. ใช้การอัปโหลดไฟล์
2.1. หน้าอัปโหลดไฟล์และหน้าพรอมต์ข้อความ
รหัสของหน้า upload.jsp มีดังนี้:
<%@ page language = "java" pageencoding = "utf-8"%> <! doctype html> <html> <head> <title> ไฟล์ upload </title> </head> <body> <form action = "$ {pageContext.Request.ContextPath}/servlet/servlet ผู้ใช้: <อินพุต type = "text" name = "username"> <br/> อัปโหลดไฟล์ 1: <input type = "file" name = "file1"> <br/> อัปโหลดไฟล์ 2: <input type = "file" name = "file2"> <br/> พิมพ์? <%@ page language = "java" pageencoding = "utf-8"%> <! doctype html> <html> <head> <title> ข้อความแจ้งข้อความ </title> </head> <body> $ {ข้อความ} </body> </html>2.2. การประมวลผล servlets สำหรับการอัปโหลดไฟล์
รหัสของ UploadHandleservlet มีดังนี้:
แพ็คเกจ me.gacl.web.controller; นำเข้า Java.io.File; นำเข้า Java.io.FileOutputStream; นำเข้า java.io.ioException; นำเข้า Java.io.InputStream; นำเข้า java.util.list; นำเข้า javax.servlet.servletexception; นำเข้า Javax.servlet.http.httpservlet; นำเข้า Javax.servlet.http.httpservletRequest; นำเข้า Javax.servlet.http.httpservletResponse; นำเข้า org.apache.Commons.FileUpload.FileItem; นำเข้า org.apache.commons.fileupload.disk.diskfileitemfactory; นำเข้า org.apache.commons.fileupload.servlet.servletFileUpload; Public Class UploadHandleservlet ขยาย httpservlet {โมฆะสาธารณะ doget (httpservletrequest คำขอ httpservletresponse) พ่น servletexception, ioexception {// รับไดเรกทอรีที่บันทึกไว้ในไฟล์ที่อัปโหลด this.getServletContext (). getRealPath ("/web-inf/upload"); ไฟล์ไฟล์ = ไฟล์ใหม่ (บันทึก); // ตัดสินว่าไดเรกทอรีที่บันทึกไว้ของไฟล์ที่อัปโหลดนั้นมีอยู่หรือไม่ถ้า (! file.exists () &&! file.isdirectory ()) {system.out.println (ไดเรกทอรี savepath+"ไม่มีอยู่มันจะต้องถูกสร้างขึ้น"); // สร้าง directory file.mkdir (); } // ข้อความแจ้งข้อความสตริง = ""; ลอง {// ใช้องค์ประกอบอัปโหลดไฟล์ Apache เพื่อจัดการขั้นตอนการอัปโหลดไฟล์: // 1 สร้างโรงงาน diskfileitemfactory diskfileitemfactory โรงงาน = ใหม่ diskfileitemfactory (); // 2. สร้างไฟล์อัปโหลด parser servletFileUpload upload = ใหม่ servletFileUpload (โรงงาน); // แก้การอัปโหลดที่อ่านไม่ออกภาษาจีน Setheaderencoding ("UTF-8"); // 3. ตรวจสอบว่าข้อมูลที่ส่งเป็นข้อมูลของแบบฟอร์มการอัปโหลดหรือไม่หาก (! ServletFileUpload.ismultipartContent (คำขอ)) {// รับข้อมูลคืนข้อมูลแบบดั้งเดิม } // 4 ใช้ตัวแยกวิเคราะห์ servletFileUpload เพื่อแยกวิเคราะห์ข้อมูลที่อัปโหลด ผลลัพธ์การแยกวิเคราะห์ส่งคืนรายการ <fileitem> รายการคอลเลกชัน FileItem แต่ละรายการสอดคล้องกับรายการอินพุตของรายการฟอร์มรายการ <fileItem> list = upload.parserequest (คำขอ); สำหรับ (รายการ fileitem: list) {// ถ้าข้อมูลของรายการอินพุตปกติถูกห่อหุ้มใน fileItem ถ้า (item.isformfield ()) {string name = item.getFieldName (); // แก้ปัญหาที่อ่านไม่ออกภาษาจีนของข้อมูลของรายการอินพุตทั่วไปค่าสตริง = item.getString ("UTF-8"); // value = สตริงใหม่ (value.getBytes ("ISO8859-1"), "UTF-8"); System.out.println (ชื่อ + "=" + ค่า); } else {// ถ้ารายการไฟล์ห่อหุ้มไฟล์ที่อัปโหลด // รับชื่อไฟล์ที่อัปโหลดชื่อสตริง filename = item.getName (); System.out.println (ชื่อไฟล์); if (filename == null || filename.trim (). เท่ากับ ("")) {ดำเนินการต่อ; } // หมายเหตุ: ชื่อไฟล์ที่ส่งโดยเบราว์เซอร์ต่าง ๆ จะแตกต่างกัน เบราว์เซอร์บางตัวส่งไฟล์ที่มีพา ธ เช่น: C: /a/b/1.txt และบางชื่อเป็นเพียงชื่อไฟล์ง่าย ๆ เช่น: 1.txt // ประมวลผลส่วนพา ธ ของชื่อไฟล์ของไฟล์ที่ได้รับที่ได้รับเพียงส่วนชื่อไฟล์เท่านั้น // รับสตรีมอินพุตของไฟล์ที่อัปโหลดในรายการอินพุตสตรีมใน = item.getInputStream (); // สร้างสตรีมเอาต์พุตไฟล์ FileOutputStream OUT = ใหม่ fileOutputStream (savepath + "//" + ชื่อไฟล์); // สร้างบัฟเฟอร์บัฟเฟอร์บัฟเฟอร์ [] = ไบต์ใหม่ [1024]; // การระบุว่าข้อมูลในสตรีมอินพุตได้รับการอ่านเป็น int len = 0; // สตรีมอินพุตถูกอ่านลงในลูปบัฟเฟอร์ (len = in.read (บัฟเฟอร์))> 0 หมายความว่ายังมีข้อมูลอยู่ในขณะที่ ((len = in.read (บัฟเฟอร์))> 0) {// ใช้สตรีมเอาต์พุต fileOutputStream เพื่อเขียนข้อมูลบัฟเฟอร์ลงในไดเรกทอรีที่ระบุ } // ปิดสตรีมอินพุต in.close (); // ปิดสตรีมเอาต์พุตออก close (); // ลบไฟล์ชั่วคราวที่สร้างขึ้นเมื่อประมวลผลไฟล์อัปโหลด item.delete (); ข้อความ = "อัปโหลดไฟล์ได้สำเร็จ!"; }}}} catch (Exception e) {message = "การอัปโหลดไฟล์ล้มเหลว!"; E.PrintStackTrace (); } request.setAttribute ("ข้อความ", ข้อความ); request.getRequestDispatcher ("/message.jsp") ส่งต่อ (คำขอ, การตอบกลับ); } โมฆะสาธารณะ dopost (คำขอ httpservletrequest, httpservletResponse การตอบสนอง) พ่น servletexception, ioexception {doget (คำขอ, การตอบสนอง); -ลงทะเบียน uploadhandleservlet ในไฟล์ web.xml
<servlet> <servlet-name> uploadhandleservlet </servlet-name> <servlet-lass> me.gacl.web.controller.uploadhandleservlet </servlet-lass> </servlet> <servlet-mapping> <servlet-name> </servlet-mapping>
เอฟเฟกต์การดำเนินการมีดังนี้:
หลังจากอัปโหลดไฟล์สำเร็จไฟล์ที่อัปโหลดจะถูกบันทึกไว้ในไดเรกทอรีอัปโหลดภายใต้ไดเรกทอรี Web-Inf ดังแสดงในรูปด้านล่าง:
2.3. รายละเอียดการอัปโหลดไฟล์
แม้ว่ารหัสข้างต้นสามารถอัปโหลดไฟล์ไปยังไดเรกทอรีที่ระบุบนเซิร์ฟเวอร์ได้สำเร็จ แต่ก็มีรายละเอียดเล็ก ๆ น้อย ๆ มากมายที่ต้องให้ความสนใจในฟังก์ชั่นการอัปโหลดไฟล์ ประเด็นต่อไปนี้ควรได้รับความสนใจเป็นพิเศษ
1. เพื่อให้แน่ใจว่าความปลอดภัยของเซิร์ฟเวอร์ควรวางไฟล์ไว้ในไดเรกทอรีที่ไม่สามารถเข้าถึงได้โดยตรงจากโลกภายนอกเช่นในไดเรกทอรี Web-Inf
2. เพื่อป้องกันการเขียนทับไฟล์ต้องสร้างชื่อไฟล์ที่ไม่ซ้ำกันสำหรับการอัปโหลดไฟล์
3. เพื่อป้องกันไม่ให้ไฟล์มากเกินไปปรากฏภายใต้ไดเรกทอรีคุณต้องใช้อัลกอริทึมแฮชเพื่อแยกพื้นที่เก็บข้อมูล
4. ค่าสูงสุดของไฟล์ที่อัปโหลดควรมี จำกัด
5. หากต้องการ จำกัด ประเภทของไฟล์ที่อัปโหลดเมื่อได้รับชื่อไฟล์ที่อัปโหลดให้พิจารณาว่าชื่อต่อท้ายนั้นถูกกฎหมายหรือไม่
ในการตอบสนองต่อปัญหารายละเอียด 5 ข้างต้นให้ปรับปรุง UploadHandleservlet รหัสที่ได้รับการปรับปรุงมีดังนี้:
แพ็คเกจ me.gacl.web.controller; นำเข้า Java.io.File; นำเข้า Java.io.FileOutputStream; นำเข้า java.io.ioException; นำเข้า Java.io.InputStream; นำเข้า java.util.list; นำเข้า java.util.uuid; นำเข้า javax.servlet.servletexception; นำเข้า Javax.servlet.http.httpservlet; นำเข้า javax.servlet.http.httpservletrequest; นำเข้า Javax.servlet.http.httpservletResponse; นำเข้า org.apache.Commons.FileUpload.FileItem; นำเข้า org.apache.Commons.FileUpload.FileUploadBase; นำเข้า org.apache.commons.fileupload.progresslistener; นำเข้า org.apache.commons.fileupload.disk.diskfileitemfactory; นำเข้า org.apache.commons.fileupload.servlet.servletFileUpload; / ** * @className: UploadHandleservlet * @description: todo (ฉันใช้หนึ่งประโยคเพื่ออธิบายฟังก์ชั่นของคลาสนี้) * @author: รับประกัน Canglang * @date: 2015-1-3 11:35:50 PM * */ คลาสสาธารณะ UploadHandleservlet ServleTexception, iOexception {// รับไดเรกทอรีที่บันทึกไว้ของไฟล์ที่อัปโหลดจัดเก็บไฟล์ที่อัปโหลดในไดเรกทอรี Web-Inf และไม่อนุญาตให้เข้าถึงโดยตรงจากโลกภายนอกเพื่อให้แน่ใจว่าการรักษาความปลอดภัยของสตริงไฟล์ที่อัปโหลด = this.getServletContext () // ไฟล์ชั่วคราวที่สร้างขึ้นระหว่างการอัปโหลดจะถูกบันทึกโดยสตริงไดเรกทอรี temppath = this.getServletContext (). getRealPath ("/web-inf/temp"); ไฟล์ tmpfile = ไฟล์ใหม่ (temppath); if (! tmpfile.exists ()) {// สร้างไดเรกทอรีชั่วคราว tmpfile.mkdir (); } // ข้อความแจ้งข้อความสตริง = ""; ลอง {// ใช้องค์ประกอบอัปโหลดไฟล์ Apache เพื่อจัดการขั้นตอนการอัปโหลดไฟล์: // 1 สร้างโรงงาน diskfileitemfactory diskfileitemfactory โรงงาน = ใหม่ diskfileitemfactory (); // ตั้งค่าขนาดของบัฟเฟอร์ของโรงงาน เมื่อขนาดไฟล์ที่อัปโหลดเกินขนาดของบัฟเฟอร์ไฟล์ชั่วคราวจะถูกสร้างและเก็บไว้ในไดเรกทอรีชั่วคราวที่ระบุ Factory.SetSizEthreshold (1024*100); // ตั้งค่าขนาดบัฟเฟอร์เป็น 100KB หากไม่ได้ระบุขนาดบัฟเฟอร์คือ 10KB ตามค่าเริ่มต้น // ตั้งค่าไดเรกทอรีที่เก็บข้อมูลของไฟล์ชั่วคราวที่สร้างขึ้นระหว่างการอัปโหลดโรงงาน SetRepository (TMPFile); // 2. สร้างไฟล์อัปโหลด parser servletFileUpload upload = ใหม่ servletFileUpload (โรงงาน); // ฟังไฟล์อัพโหลดความคืบหน้าการอัปโหลด SetProgressListener (ใหม่ ProgressionListener () {การอัปเดตโมฆะสาธารณะ (PBYTESREAD ยาว, PCONTENTENGTING ยาว, int arg2) {system.out.println ("ขนาดไฟล์คือ:" pcontentlength + ",:" pbytesread); /** 14608 ประมวลผลในปัจจุบัน: 7367 ขนาดไฟล์คือ: 14608, ประมวลผลในปัจจุบัน: 11419 ขนาดไฟล์คือ: 14608, ประมวลผลในปัจจุบัน: 14608 */}}); // แก้การอัปโหลดที่อ่านไม่ออกภาษาจีน Setheaderencoding ("UTF-8"); // 3. ตรวจสอบว่าข้อมูลที่ส่งเป็นข้อมูลของแบบฟอร์มการอัปโหลดหรือไม่หาก (! ServletFileUpload.ismultipartContent (คำขอ)) {// รับข้อมูลคืนข้อมูลแบบดั้งเดิม } // ตั้งค่าสูงสุดของขนาดของไฟล์เดียวที่อัปโหลดซึ่งปัจจุบันตั้งค่าเป็น 1024*1024 ไบต์นั่นคือ 1MB upload.SetFilesizEmax (1024*1024); // ตั้งค่าสูงสุดของจำนวนทั้งหมดของไฟล์ที่อัปโหลดค่าสูงสุด = ผลรวมของขนาดสูงสุดของไฟล์หลายไฟล์ที่อัปโหลดในเวลาเดียวกันซึ่งปัจจุบันตั้งค่าเป็น 10MB upload.SetSizemax (1024*1024*10); // 4. ใช้ตัวแยกวิเคราะห์ servletFileUpload เพื่อแยกวิเคราะห์ข้อมูลที่อัปโหลด ผลลัพธ์การแยกวิเคราะห์ส่งคืนรายการ <fileitem> การรวบรวมแต่ละรายการ FileItem สอดคล้องกับรายการอินพุตของรายการฟอร์มฟอร์มรายการ <fileItem> list = upload.parserequest (คำขอ); สำหรับ (FileItem item: list) {// ถ้า fileitem ห่อหุ้มข้อมูลของรายการอินพุตทั่วไปถ้า (item.isformfield ()) {string name = item.getfieldName (); // แก้ปัญหาที่อ่านไม่ออกภาษาจีนของข้อมูลของรายการอินพุตทั่วไปค่าสตริง = item.getString ("UTF-8"); // value = สตริงใหม่ (value.getBytes ("ISO8859-1"), "UTF-8"); System.out.println (ชื่อ + "=" + ค่า); } else {// ถ้า fileItem ห่อหุ้มไฟล์ที่อัปโหลด // รับชื่อไฟล์ที่อัปโหลดชื่อสตริง filename = item.getName (); System.out.println (ชื่อไฟล์); if (filename == null || filename.trim (). เท่ากับ ("")) {ดำเนินการต่อ; } // หมายเหตุ: ชื่อไฟล์ที่ส่งโดยเบราว์เซอร์ต่าง ๆ จะแตกต่างกัน เบราว์เซอร์บางตัวส่งชื่อไฟล์ที่มีพา ธ เช่น: C: /a/b/1.txt ในขณะที่บางชื่อเป็นเพียงชื่อไฟล์ง่าย ๆ เช่น: 1.txt // ประมวลผลส่วนพา ธ ของชื่อไฟล์ของไฟล์ที่ได้รับที่ได้รับเพียงส่วนชื่อไฟล์เท่านั้น // รับส่วนขยายของสตริงไฟล์ที่อัปโหลด fileextName = filename.substring (filename.lastindexof (".")+1); // หากคุณต้องการ จำกัด ประเภทไฟล์ที่อัปโหลดคุณสามารถใช้นามสกุลไฟล์เพื่อพิจารณาว่าประเภทไฟล์ที่อัปโหลดเป็นระบบกฎหมายหรือไม่ ("ส่วนขยายของไฟล์ที่อัปโหลดคือ:"+fileextName); // รับสตรีมอินพุตของไฟล์ที่อัปโหลดในรายการอินพุตสตรีมใน = item.getInputStream (); // รับชื่อของไฟล์ที่บันทึกไว้สตริง saveFileName = makeFileName (ชื่อไฟล์); // รับไฟล์บันทึกสตริงไดเรกทอรี realsavepath = makePath (savefilename, savepath); // สร้าง File Output Stream FileOutputStream = ใหม่ fileOutputStream (RealSavePath + "//" + saveFileName); // สร้างบัฟเฟอร์บัฟเฟอร์บัฟเฟอร์ [] = ไบต์ใหม่ [1024]; // การระบุของการพิจารณาว่าข้อมูลในสตรีมอินพุตได้รับการอ่านหรือไม่นั้นเป็น int len = 0; // สตรีมอินพุตถูกอ่านลงในบัฟเฟอร์ (len = in.read (บัฟเฟอร์))> 0 หมายความว่ายังมีข้อมูลอยู่ในขณะที่ ((len = in.read (บัฟเฟอร์))> 0) {// ใช้สตรีมเอาต์พุต fileOutputStream เพื่อเขียนข้อมูลบัฟเฟอร์ลงในไดเรกทอรีที่ระบุ } // ปิดสตรีมอินพุต in.close (); // ปิดสตรีมเอาต์พุตออก close (); // ลบไฟล์ชั่วคราวที่สร้างขึ้นเมื่อประมวลผลการอัปโหลดไฟล์ //item.delete (); ข้อความ = "อัปโหลดไฟล์ได้สำเร็จ!"; }}} catch (fileuploadbase.filesizeLimitexceedEdException E) {E.printStackTrace (); request.setAttribute ("ข้อความ", "ค่าสูงสุดของไฟล์เดียวเกิน !!!"); request.getRequestDispatcher ("/message.jsp") ส่งต่อ (คำขอ, การตอบกลับ); กลับ; } catch (fileuploadbase.sizeLimitexceedEdException e) {E.printStackTrace (); request.setAttribute ("ข้อความ", "ขนาดรวมของไฟล์ที่อัปโหลดเกินกว่าค่าสูงสุดของขีด จำกัด !!!"); request.getRequestDispatcher ("/message.jsp") ส่งต่อ (คำขอ, การตอบกลับ); กลับ; } catch (Exception e) {message = "การอัปโหลดไฟล์ล้มเหลว!"; E.PrintStackTrace (); } request.setAttribute ("ข้อความ", ข้อความ); request.getRequestDispatcher ("/message.jsp") ส่งต่อ (คำขอ, การตอบกลับ); } / *** @method: makefileName* @description: สร้างชื่อไฟล์ของไฟล์ที่อัปโหลดโดยมีชื่อไฟล์เป็น: uuid+ "_"+ ชื่อเดิมของไฟล์* @anthor: 发官网* @param filename ชื่อเดิม //2.jpg // เพื่อป้องกันการทับเอกสารไฟล์ต้องสร้างชื่อไฟล์ที่ไม่ซ้ำกันสำหรับการอัปโหลดไฟล์ return uuid.randomuuid (). toString () + "_" + ชื่อไฟล์; } / *** เพื่อป้องกันไม่ให้มีไฟล์มากเกินไปที่ปรากฏภายใต้ไดเรกทอรีคุณต้องใช้อัลกอริทึมแฮชเพื่อแยกพื้นที่เก็บข้อมูล* @method: MakePath* @description:* @anthor: Lone และ Jolfant Wolf** @param @param ชื่อไฟล์ savepath) {// รับค่า hashcode ของชื่อไฟล์และสิ่งที่คุณได้รับคือที่อยู่ของชื่อไฟล์สตริงวัตถุในหน่วยความจำ int hashcode = filename.hashCode (); int dir1 = hashcode & 0xf; // 0--15 int dir2 = (hashcode & 0xf0) >> 4; // 0-15 // สร้างสตริงไดเรกทอรีบันทึกใหม่ DIR = savepath + "//" + dir1 + "//" + dir2; // อัปโหลด/2/3 อัปโหลด/3/5 // ไฟล์สามารถแสดงทั้งไฟล์และไฟล์ไดเรกทอรีไฟล์ = ไฟล์ใหม่ (dir); // ถ้าไดเรกทอรีไม่มีอยู่ถ้า (! file.exists ()) {// สร้าง directory file.mkdirs (); } return dir; } โมฆะสาธารณะ dopost (คำขอ httpservletrequest, httpservletResponse การตอบสนอง) พ่น servletexception, ioexception {doget (คำขอ, การตอบสนอง); -หลังจากปรับปรุงรายละเอียดเล็ก ๆ ห้ารายที่กล่าวถึงข้างต้นแล้วฟังก์ชั่นการอัปโหลดไฟล์ของเราค่อนข้างสมบูรณ์
3. ดาวน์โหลดไฟล์
3.1. แสดงรายการทรัพยากรไฟล์ที่มีให้เพื่อดาวน์โหลด
เราต้องการให้ทรัพยากรไฟล์ในระบบเว็บแอปพลิเคชันแก่ผู้ใช้สำหรับดาวน์โหลด ก่อนอื่นเราต้องมีหน้าเพื่อแสดงรายการไฟล์ทั้งหมดในไดเรกทอรีไฟล์ที่อัปโหลด เมื่อผู้ใช้คลิกที่ไฟล์ไฮเปอร์ลิงก์จะถูกดาวน์โหลดและเขียน ListFilesERVLET เพื่อแสดงรายการไฟล์ที่ดาวน์โหลดทั้งหมดในระบบเว็บแอปพลิเคชัน
รหัสของ ListFileservlet มีดังนี้:
แพ็คเกจ me.gacl.web.controller; นำเข้า Java.io.File; นำเข้า java.io.ioException; นำเข้า java.util.hashmap; นำเข้า java.util.map; นำเข้า javax.servlet.servletexception; นำเข้า Javax.servlet.http.httpservlet; นำเข้า javax.servlet.http.httpservletrequest; นำเข้า Javax.servlet.http.httpservletResponse; / ** * @className: ListFilesERVLET * @description: รายการไฟล์ที่ดาวน์โหลดทั้งหมดในระบบเว็บ * @author: รับประกัน * @date: 2015-1-4 9:54:40 PM * */ คลาสสาธารณะ // รับไดเรกทอรีสำหรับการอัปโหลดสตริงไฟล์ uploadFilePath = this.getServletContext (). getRealPath ("/web-inf/upload"); // การจัดเก็บชื่อไฟล์ที่จะดาวน์โหลดแผนที่ <สตริงสตริง> filenamemap = ใหม่ hashmap <สตริงสตริง> (); // การสำรวจไฟล์และไดเรกทอรีทั้งหมดซ้ำ ๆ ในไดเรกทอรี FilePath และจัดเก็บชื่อไฟล์ของไฟล์ในการรวบรวมแผนที่ ListFile (ไฟล์ใหม่ (uploadFilePath), filenamemap); // ไฟล์สามารถแสดงไฟล์หรือไดเรกทอรี // ส่งแผนที่ request.getRequestDispatcher ("/listfile.jsp"). forward (คำขอ, การตอบกลับ); } /*** @method: listfile* @description: traverse traverse ไฟล์ทั้งหมดในไดเรกทอรีที่ระบุ* @anthor: 光克* @param ไฟล์หมายถึงไฟล์และแสดงถึงไดเรกทอรีไฟล์* @param แผนที่คอลเลกชันที่เก็บชื่อไฟล์ if (! file.isfile ()) {// แสดงรายการไฟล์และไดเรกทอรีทั้งหมดในไฟล์ไฟล์ไดเรกทอรี [] = file.listfiles (); // โอนไฟล์ [] อาร์เรย์สำหรับ (ไฟล์ f: ไฟล์) {// listfile แบบเรียกซ้ำ (f, แผนที่); }} else { /*** ประมวลผลชื่อไฟล์ ไฟล์ที่อัปโหลดถูกเปลี่ยนชื่อในรูปแบบของชื่อ UUID_FILE ลบส่วน UUID_ ของชื่อไฟล์ file.getName (). indexof ("_") เพื่อดึงตำแหน่งของอักขระ "_" ในสตริง หากชื่อไฟล์คล้ายกับ: 9349249849-88343-8344_A_FAN_DAVI.AVI ดังนั้น file.getName (). substring (file.getName (). indexof ("_")+1) สามารถรับ A_FAN_DAVI.AVI file.getName (). substring (file.getName (). indexof ("_")+1); //file.getName () รับชื่อเดิมของไฟล์ ชื่อนี้ไม่ซ้ำกันดังนั้นจึงสามารถใช้เป็นคีย์ได้ RealName เป็นชื่อที่ประมวลผล อาจเป็น map.put ซ้ำ (file.getName (), realName); }} โมฆะสาธารณะ dopost (คำขอ httpservletrequest, การตอบสนอง httpservletResponse) พ่น servletexception, ioexception {doget (คำขอ, การตอบกลับ); - ที่นี่ฉันพูดคุยสั้น ๆ เกี่ยวกับวิธี ListFile ใน ListFileservlet เมธอด ListFile ใช้ในการแสดงรายการไฟล์ทั้งหมดในไดเรกทอรี วิธี ListFile ใช้การเรียกซ้ำ ในการพัฒนาจริงเราจะสร้างตารางในฐานข้อมูลอย่างแน่นอนซึ่งจะจัดเก็บชื่อไฟล์ที่อัปโหลดและไดเรกทอรีที่เก็บข้อมูลเฉพาะของไฟล์ เราสามารถรู้ไดเรกทอรีที่เก็บข้อมูลเฉพาะของไฟล์โดยการสอบถามตารางและไม่จำเป็นต้องใช้การดำเนินการซ้ำ ตัวอย่างนี้เป็นเพราะฐานข้อมูลไม่ได้จัดเก็บชื่อไฟล์ที่อัปโหลดและตำแหน่งที่เก็บข้อมูลเฉพาะของไฟล์และตำแหน่งที่เก็บข้อมูลของไฟล์ที่อัปโหลดจะใช้เพื่อแยกพื้นที่เก็บข้อมูลดังนั้นจำเป็นต้องมีการเรียกซ้ำ ในระหว่างการเรียกซ้ำชื่อไฟล์ที่ได้รับจะถูกเก็บไว้ในคอลเลกชันแผนที่ที่ส่งผ่านจากภายนอกไปยังวิธี ListFile ดังนั้นเราจึงสามารถมั่นใจได้ว่าไฟล์ทั้งหมดจะถูกเก็บไว้ในคอลเลกชันแผนที่เดียวกัน
กำหนดค่า listfileservlet ในไฟล์ web.xml
<servlet> <servlet-name> listfileservlet </servlet-name> <servlet-lass> me.gacl.web.controller.listfileservlet </servlet-lass> </servlet> <servlet-mapping>
หน้า listfile.jsp ที่แสดงไฟล์ที่ดาวน์โหลดมีดังนี้:
<%@ page language = "java" import = "java.util.*" pageencoding = "utf-8"%> <%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core"%> <! <!-คอลเลกชันแผนที่ทราเวอร์ส-> <c: foreach var = "me" items = "$ {filenamemap}"> <c: url value = "/servlet/downloadservlet" var = "downurl"> <c: param = "filename" value = "$ {me.key}" href = "$ {downurl}"> ดาวน์โหลด </a> <br/> </c: foreach> </body> </html> โดยการเข้าถึง ListFilesERVLET คุณสามารถแสดงทรัพยากรไฟล์ที่ให้แก่ผู้ใช้เพื่อดาวน์โหลดในหน้า ListFile.jsp ดังแสดงในรูปด้านล่าง:
3.2. ใช้ไฟล์ดาวน์โหลด
เขียน servlet สำหรับการดาวน์โหลดไฟล์การประมวลผล รหัสสำหรับการดาวน์โหลด Servlet มีดังนี้:
แพ็คเกจ me.gacl.web.controller; นำเข้า Java.io.File; นำเข้า Java.io.FileInputStream; นำเข้า java.io.ioException; นำเข้า Java.io.OutputStream; นำเข้า java.net.urlencoder; นำเข้า javax.servlet.servletexception; นำเข้า Javax.servlet.http.httpservlet; นำเข้า javax.servlet.http.httpservletrequest; นำเข้า Javax.servlet.http.httpservletResponse; Public Class DownloadLoadServlet ขยาย httpservlet {โมฆะสาธารณะ doget (คำขอ httpservletrequest, httpservletResponse การตอบสนอง) พ่น servletexception, ioexception {// รับชื่อไฟล์ที่จะดาวน์โหลดสตริง filename = request.get.gatarameter ("filename"); //23239283-92489-avatar.avi filename = สตริงใหม่ (filename.getBytes ("ISO8859-1"), "UTF-8"); // ไฟล์ที่อัปโหลดจะถูกบันทึกไว้ในไดเรกทอรีย่อยของ/web-inf/upload สตริงสตริง filesaverootpath = this.getServletContext (). getRealPath ("/web-inf/upload"); // ค้นหาไดเรกทอรีที่ไฟล์อยู่โดยชื่อสตริงชื่อไฟล์ = findFilesavePathByFileName (ชื่อไฟล์, fileName, filesaverootpath); // รับไฟล์ที่จะดาวน์โหลดไฟล์ = ไฟล์ใหม่ (path + "//" + ชื่อไฟล์); // หากไฟล์ไม่มีอยู่ถ้า (! file.exists ()) {request.setAttribute ("ข้อความ", "ทรัพยากรที่คุณต้องการดาวน์โหลดถูกลบไปแล้ว !!"); request.getRequestDispatcher ("/message.jsp") ส่งต่อ (คำขอ, การตอบกลับ); กลับ; } // การประมวลผลชื่อไฟล์สตริง realname = filename.substring (filename.indexof ("_")+1); // ตั้งส่วนหัวการตอบกลับเพื่อควบคุมเบราว์เซอร์เพื่อดาวน์โหลดการตอบสนองของไฟล์ Setheader ("เนื้อหา-การจัดสรร", "ไฟล์แนบ; filename =" + urlencoder.encode (realName, "UTF-8")); // อ่านไฟล์ที่จะดาวน์โหลดและบันทึกไปยังสตรีมการป้อนข้อมูลสตรีม FileInputStream ใน = ใหม่ FileInputStream (พา ธ + "//" + ชื่อไฟล์); // สร้างเอาท์พุทสตรีมเอาท์พุทสตรีมออก = response.getOutputStream (); // สร้างบัฟเฟอร์บัฟเฟอร์บัฟเฟอร์ [] = ไบต์ใหม่ [1024]; int len = 0; // loop อ่านเนื้อหาของสตรีมอินพุตลงในบัฟเฟอร์ในขณะที่ ((len = in.read (บัฟเฟอร์))> 0) {// เอาต์พุตเนื้อหาของบัฟเฟอร์ไปยังเบราว์เซอร์เพื่อรับรู้การดาวน์โหลดไฟล์ out.write (บัฟเฟอร์, 0, len); } // ปิดสตรีมอินพุทไฟล์ in.close (); // ปิดสตรีมเอาต์พุตออก close (); } /*** @Method: FindFilesAvePathByFiLEname* @Description: ค้นหาเส้นทางของไฟล์ที่จะดาวน์โหลดผ่านชื่อไฟล์และไดเรกทอรีรูทที่เก็บข้อมูล* @anthor: 发官网* @param ชื่อไฟล์ชื่อไฟล์* @param saverirlives String findFilesAvePathByFiLENAME (ชื่อไฟล์สตริง, สตริง saverootpath) {int hashCode = filename.hashCode (); int dir1 = hashcode & 0xf; // 0--15 int dir2 = (hashcode & 0xf0) >> 4; // 0-15 String dir = saverootpath + "//" + dir1 + "//" + dir2; // อัปโหลด/2/3 อัปโหลด/3/5 ไฟล์ไฟล์ = ไฟล์ใหม่ (dir); if (! file.exists ()) {// สร้าง directory file.mkdirs (); } return dir; } โมฆะสาธารณะ dopost (คำขอ httpservletrequest, httpservletResponse การตอบสนอง) พ่น servletexception, ioexception {doget (คำขอ, การตอบสนอง); -การกำหนดค่า downloadservlet ในไฟล์ web.xml
<servlet> <servlet-name> downloadservlet </servlet-name> <servlet-lass> me.gacl.web.controller.downloadservlet </servlet-lass> </servlet> <servlet-mapping> <servlet-name> ดาวน์โหลด
คลิกที่ [ดาวน์โหลด] ไฮเปอร์ลิงก์ส่งคำขอไปยัง DownloadServlet และดำเนินการเพื่อให้ได้ไฟล์ดาวน์โหลด เอฟเฟกต์การดำเนินการแสดงในรูปด้านล่าง:
จากผลลัพธ์ที่รันเราจะเห็นว่าฟังก์ชั่นการดาวน์โหลดไฟล์ของเราสามารถดาวน์โหลดไฟล์ได้ตามปกติ
ข้างต้นเป็นคำอธิบายที่ละเอียดที่สุดของตัวอย่างการอัปโหลดและดาวน์โหลดไฟล์ที่แนะนำโดยตัวแก้ไข (แนะนำ) ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับทุกคนในเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!