บทคัดย่อ: บทความนี้แนะนำสองวิธีสำหรับ JavaBean เพื่อใช้อัพโหลดไฟล์หลายไฟล์ โดยใช้โปรโตคอล http และโปรโตคอล ftp ตามลำดับ ขั้นแรก จะอธิบายรูปแบบพื้นฐานของการถ่ายโอนหลายไฟล์ผ่านโปรโตคอล http และกระบวนการอัปโหลดโดยละเอียด จากนั้นจะแนะนำการใช้คลาส ftpclient เพื่อใช้งานการอัปโหลด ftp และสุดท้ายจะเปรียบเทียบทั้งสองวิธี
คำสำคัญ: JavaBean, http, ftp, ftpclient
JavaBean เป็นส่วนประกอบซอฟต์แวร์ที่ใช้ Java JSP จัดเตรียมการสนับสนุนที่สมบูรณ์สำหรับการรวมคอมโพเนนต์ JavaBean ในเว็บแอปพลิเคชัน การสนับสนุนนี้ไม่เพียงแต่ทำให้เวลาการพัฒนาสั้นลงเท่านั้น (คุณสามารถใช้ส่วนประกอบที่มีอยู่ที่ได้รับการทดสอบและเชื่อถือได้โดยตรง หลีกเลี่ยงการพัฒนาซ้ำ) แต่ยังนำความสามารถในการขยายขนาดมาสู่แอปพลิเคชัน JSP ได้มากขึ้นอีกด้วย
ฟังก์ชันอัพโหลดไฟล์เป็นเรื่องปกติมากในรูปแบบการพัฒนาแบบ B/S เมื่อเปรียบเทียบกับเครื่องมือพัฒนาอื่นๆ JSP ยังไม่รองรับการอัพโหลดไฟล์อย่างสมบูรณ์แบบ เนื่องจาก JSP ไม่ต้องใช้คอมโพเนนต์ในการทำให้สมบูรณ์เหมือน ASP และไม่ได้ให้การสนับสนุนโดยตรงสำหรับการอัพโหลดไฟล์เช่น PHP วิธีที่ JSP ใช้ในการอัปโหลดไฟล์มีดังนี้: ใช้เมธอด getInputStream() ของคลาส ServletRequest เพื่อรับสตรีมข้อมูลที่ไคลเอ็นต์ส่งไปยังเซิร์ฟเวอร์ จากนั้นประมวลผลสตรีมข้อมูลนี้เพื่อวิเคราะห์และรับพารามิเตอร์และพารามิเตอร์ต่างๆ ที่ส่งไปยัง เซิร์ฟเวอร์ระหว่างการอัพโหลดไฟล์ข้อมูลแล้วจัดเก็บข้อมูลไฟล์ไว้เป็นไฟล์หรือแทรกลงในฐานข้อมูล โดยปกติเพจ JSP จะไม่จัดการกับฟังก์ชันอัพโหลดไฟล์ แต่ใส่ฟังก์ชันเหล่านี้ลงใน Servlets หรือ JavaBeans เพื่อนำไปใช้ ตัวอย่างของการใช้ Servlet เพื่อทำการอัพโหลดไฟล์มีอยู่ในหนังสือที่เกี่ยวข้องกับ JSP บางเล่ม ที่นี่ ผมจะแนะนำวิธีการใช้ JeanBean เพื่อทำการอัพโหลดไฟล์ให้เสร็จสิ้น มีสองวิธีในการอัปโหลดไฟล์ใน JSP ได้แก่ โปรโตคอล HTTP และโปรโตคอล FTP หลักการส่งข้อมูลระหว่างทั้งสองมีความแตกต่างกันมาก ต่อไปนี้จะให้คำแนะนำสั้น ๆ เกี่ยวกับการนำไปใช้งานโดยอิงตามซอร์สโค้ด ฉันเชื่อว่าผู้อ่านจะได้ประโยชน์บางอย่างจากซอร์สโค้ด โปรแกรมต่อไปนี้ได้รับการแก้ไขและผ่านแล้ว สภาพแวดล้อมการดีบัก: เซิร์ฟเวอร์ window 2000+Apache +tomcat4.0, สภาพแวดล้อมการดีบัก JavaBean: JDK1.4+Editplus
การใช้ JavaBean ใน JSP เพื่อใช้งานฟังก์ชันอัพโหลดไฟล์บนเว็บ โดยทั่วไปต้องใช้ไฟล์สามประเภทรวมกัน ไฟล์ทั้งสามนี้เป็นไฟล์เพจ HTML ที่ให้อินเทอร์เฟซตามลำดับ ไฟล์ JSP ที่ดำเนินการเรียกเพื่อใช้ฟังก์ชันอัพโหลดของ JavaBean และไฟล์คลาส Java ที่ใช้ JavaBean ตามลำดับ ด้านล่างนี้ฉันจะเน้นที่ส่วน JavaBean ที่ใช้โปรโตคอล HTTP และโปรโตคอล FTP เพื่อใช้ฟังก์ชันอัพโหลดไฟล์
1 ใช้โปรโตคอล HTTP เพื่ออัปโหลดหลายไฟล์
ในอดีต Html ไม่สามารถอัปโหลดไฟล์ได้ ซึ่งค่อนข้างจำกัดฟังก์ชันของหน้าเว็บบางหน้า ข้อกำหนด RFC1867 (นั่นคือ การอัปโหลดไฟล์ตามแบบฟอร์มใน Html) จะขยายแบบฟอร์มและเพิ่มองค์ประกอบแบบฟอร์ม <input type=file> โดยใช้องค์ประกอบนี้ เบราว์เซอร์จะสร้างกล่องอินพุตและปุ่มโดยอัตโนมัติ กล่องอินพุตอนุญาตให้ผู้ใช้กรอกชื่อไฟล์ในเครื่องและชื่อพาธ และปุ่มอนุญาตให้เบราว์เซอร์เปิดกล่องเลือกไฟล์สำหรับผู้ใช้ เลือกไฟล์ การใช้งานแบบฟอร์มเฉพาะมีดังนี้:
<FORMMETHOD="POST" ACTION="*.jsp" ENCTYPE="multipart/form-data">
<INPUT TYPE="FILE" NAME="FILE1" SIZE="50"><BR>
<INPUT TYPE="ส่ง" VALUE="อัปโหลด">
</FORM>
เมื่อคุณเลือกที่จะวางไฟล์ ให้ป้อนเส้นทางที่แน่นอนของไฟล์ในเครื่องโดยตรง ค่าแอตทริบิวต์การดำเนินการของแบบฟอร์มคือ *.jsp ซึ่งหมายความว่าคำขอ (รวมถึงไฟล์ที่อัปโหลด) จะถูกส่งไปยัง *..ไฟล์ jsp ในกระบวนการนี้ การอัปโหลดไฟล์ผ่าน HTTP จะถูกนำไปใช้จริง การอัพโหลดไฟล์จากไคลเอนต์ไปยังเซิร์ฟเวอร์ได้รับการสนับสนุนโดย Common Gateway Interface (CGI) ของโปรโตคอล HTTP วิธีการอัปโหลดนี้กำหนดให้ทั้งเบราว์เซอร์และเว็บเซิร์ฟเวอร์รองรับ Rfc1867 JavaBean รับสตรีมข้อมูลที่ส่งโดยไคลเอนต์ไปยังเซิร์ฟเวอร์ผ่านเมธอด getInputStream() ของคลาส ServletRequest วิเคราะห์รูปแบบไฟล์ที่อัพโหลด และส่งออกไฟล์หลายไฟล์ไปยังไฟล์เป้าหมายบนฝั่งเซิร์ฟเวอร์ตามลำดับตามผลการวิเคราะห์ ฟังก์ชั่นของ JavaBeande ในตัวอย่างนี้ถูกนำมาใช้โดยเฉพาะโดยคลาส testUpload กรอบงานของคลาส TestUpload เป็นดังนี้:
testUpload ระดับสาธารณะ
-
ทดสอบสาธารณะอัปโหลด () {…… }
โมฆะขั้นสุดท้ายสาธารณะเริ่มต้น (การกำหนดค่า ServletConfig) พ่น ServletException
{ m_application = config.getServletContext(); }
การอัปโหลดโมฆะสาธารณะ () พ่น testUploadException, IOException, ServletException
-
โมฆะส่วนตัว getDataSection(){………}
โมฆะส่วนตัว getDataHeader(){………}
บันทึก int สาธารณะ (สตริง destPathName)
พ่น SmartUploadException, IOException, ServletException
-
-
}
เริ่มต้นสภาพแวดล้อมการทำงานของ Servlet ผ่านทางวิธีการเริ่มต้น () ใช้เมธอด upload() เพื่อรับอินพุตสตรีม วิเคราะห์รูปแบบของไฟล์ที่อัพโหลด และกำหนดคุณสมบัติของไฟล์ที่อัพโหลดแต่ละไฟล์ให้กับอินสแตนซ์คลาสไฟล์หลายรายการเพื่อการประมวลผล อินสแตนซ์คลาสไฟล์เหล่านี้ได้รับการจัดการโดยคลาส Files คลาส File เรียกเมธอด save () ตามคุณสมบัติของแต่ละไฟล์เพื่อส่งออกหลายไฟล์ไปยังไฟล์เป้าหมายบนฝั่งเซิร์ฟเวอร์ตามลำดับ วิธีการ upload() เป็นกุญแจสำคัญที่ใช้ในการวิเคราะห์รูปแบบของไฟล์ที่ส่งโดยโปรโตคอล http1.1 หลังจากการทดสอบ เราจะได้รูปแบบของไฟล์สตรีมการขนส่ง ซึ่งมีประโยชน์ในการทำความเข้าใจเมธอด upload() ตัวอย่างเช่น อัปโหลดไฟล์ My Documentstt.txt รูปแบบจะเป็นดังนี้:
//ตัวแยกไฟล์
-------------------------------7d226137250336
//ส่วนหัวของข้อมูลไฟล์
การจัดการเนื้อหา: form-data; name = "FILE1"; filename = "C:Documents and SettingsAdministrator.TIMBER-4O6B0ZZ0My Documentstt.sql"
ประเภทเนื้อหา: ข้อความ/ธรรมดา
//เนื้อหาไฟล์ต้นฉบับ
สร้างข้อมูลตาราง (
ภาพเนื้อหาเป็นโมฆะ);
//ตัวคั่นของไฟล์ถัดไป
-------------------------------7d226137250336
การจัดการเนื้อหา: แบบฟอร์มข้อมูล; ชื่อ = "FILE2";
ประเภทเนื้อหา: application/octet-stream
--------------------------------7d226137250336
จากไฟล์ข้างต้น เราจะเห็นว่าเมื่ออัพโหลดหลายไฟล์ โปรโตคอล HTTP ทั้งหมด ถูกใส่เข้าไปในอินพุตสตรีมและแยกความแตกต่างด้วยตัวคั่นบางตัว ที่จริงแล้ว วิธีการ upload() คือการวิเคราะห์ไฟล์ด้านบนและกำหนดเนื้อหาของตัวคั่น รูปแบบเนื้อหาของแต่ละไฟล์ ชื่อพาธแบบเต็มของไฟล์ และจุดเริ่มต้นและจุดสิ้นสุดของข้อมูลจริงของไฟล์ สิ่งหนึ่งที่ควรทราบที่นี่คือตัวคั่นจะเป็นแบบสุ่ม ซึ่งเป็นอักขระทั้งหมดก่อนอักขระขึ้นบรรทัดแรกของไฟล์สตรีมการขนส่ง
ขั้นตอนการดำเนินการของเมธอด Upload() คือ: ขั้นแรกให้ส่งออกไฟล์สตรีมอินพุตไปยังอาร์เรย์ไบต์ m_binArray ซึ่งนำไปใช้ผ่านโค้ดต่อไปนี้
m_totalBytes=1024; อ่านทั้งหมด=0;
สำหรับ(; TotalRead < m_totalBytes; TotalRead += readBytes)
พยายาม
{ m_request.getInputStream();
readBytes = m_request.getInputStream().read(m_binArray, TotalRead, m_totalBytes - TotalRead);
}catch(Exception e){ Throw new SmartUploadException("Unable to upload.");}
วิธีการอ่านแบบหลายไบต์ในลูปถูกใช้ที่นี่ ลูปด้านบนจะอ่านข้อมูลอย่างต่อเนื่องจนกว่าอาร์เรย์จะเต็ม หากสามารถดึงไฟล์ได้อย่างสมบูรณ์ ก็สามารถดึงข้อมูลไบต์ทั้งหมดของไฟล์ได้เช่นกัน แต่เนื่องจากความเร็วเครือข่ายมักจะช้ากว่า CPU มาก จึงเป็นเรื่องง่ายสำหรับโปรแกรมที่จะล้างบัฟเฟอร์เครือข่ายก่อนที่ข้อมูลทั้งหมดจะมาถึง ในความเป็นจริง วิธีการอ่านแบบหลายไบต์จะส่งคืนค่า 0 เมื่อพยายามอ่านข้อมูลจากบัฟเฟอร์เครือข่ายที่ว่างเปล่าชั่วคราวแต่เปิดอยู่ ซึ่งหมายความว่าไม่มีข้อมูลอยู่ แต่สตรีมเครือข่ายไม่ได้ถูกปิด ในกรณีนี้ วิธีแบบไบต์เดียวจะป้องกันการทำงานของโปรแกรมที่รันอยู่ ดังนั้นลักษณะการทำงานของวิธีแบบหลายไบต์จึงดีกว่าวิธีแบบไบต์เดี่ยว read() ถัดไปอาร์เรย์ไบต์ m_binArray จะถูกวิเคราะห์ ขั้นแรกให้ค้นหาตัวคั่น ใช้เมธอด getDataHeader() เพื่อส่งคืนค่าของส่วนหัวข้อมูลไฟล์ โดยจะใช้ getDataSection() วิธีการส่งคืนข้อมูลเนื้อหาไฟล์และบันทึก ตำแหน่งเริ่มต้นและจุดสิ้นสุดของข้อมูลไฟล์ในอาร์เรย์ไบต์ จากนั้นสร้างอินสแตนซ์คลาสไฟล์ และใส่ชื่อเส้นทางแบบเต็มของไฟล์ นามสกุลของไฟล์ต้นฉบับ รูปแบบเนื้อหาไฟล์ต้นฉบับ และตำแหน่งเริ่มต้นและสิ้นสุดของข้อมูลเนื้อหาของไฟล์ลงในคุณลักษณะของอินสแตนซ์คลาสไฟล์ ค้นหาตัวคั่นถัดไปและทำซ้ำขั้นตอนข้างต้นต่อไปจนกว่าการวิเคราะห์จะเสร็จสิ้น
2 ใช้โปรโตคอล FTP เพื่ออัปโหลดไฟล์หลายไฟล์
โปรโตคอล FTP เป็นโปรโตคอลที่ใช้ในการถ่ายโอนไฟล์บนอินเทอร์เน็ต โดยกำหนดมาตรฐานสำหรับการถ่ายโอนไฟล์ร่วมกันบนอินเทอร์เน็ต การใช้ฟังก์ชันนี้ใน Java สามารถทำได้ด้วยความช่วยเหลือของคลาส FtpClient กระบวนการดำเนินการเฉพาะ: ขั้นแรกให้สร้างการเชื่อมต่อกับเซิร์ฟเวอร์ FTP เริ่มต้นวิธีการส่งไฟล์รวมถึง ASCII และ BINARY ส่งออกไฟล์ไปยังสตรีมอินพุตไฟล์ FileInputStream; ข้อมูลถูกเขียนไปยังเอาต์พุตสตรีม TelnetOutputStream (ใช้วิธีการเขียนเพื่อเขียนข้อมูลไปยังลิงก์เครือข่าย) ด้วยวิธีนี้ ไฟล์ที่มีชื่อเดียวกันกับไฟล์ต้นฉบับจะถูกคัดลอกไปยังเซิร์ฟเวอร์ ในตัวอย่างนี้ JavaBean เสร็จสิ้นกระบวนการอัพโหลดไฟล์ด้วยสามวิธี: ConnectServer(), upload() และ closeConnect() การใช้งานหลักมีดังนี้:
ftpUpload ระดับสาธารณะ
{ ชื่อไฟล์สตริง; ชื่อไฟล์สตริง1; FtpClient ftpClient;
โมฆะสาธารณะ ConnectServer (เซิร์ฟเวอร์สตริง ผู้ใช้สตริง รหัสผ่านสตริง พาธสตริง)
-
//เซิร์ฟเวอร์: ที่อยู่ IP ของเซิร์ฟเวอร์ FTP ผู้ใช้: ชื่อผู้ใช้เพื่อเข้าสู่เซิร์ฟเวอร์ FTP
//password: รหัสผ่านของชื่อผู้ใช้เพื่อเข้าสู่เซิร์ฟเวอร์ FTP; path: เส้นทางบนเซิร์ฟเวอร์ FTP
ลอง { ftpClient=new FtpClient();
ftpClient.openServer(เซิร์ฟเวอร์);
ftpClient.login(ผู้ใช้, รหัสผ่าน);
System.out.println("เข้าสู่ระบบสำเร็จ!");
ถ้า (path.length()!=0) ftpClient.cd(path);
ftpClient.binary(); }จับ (IOException เช่น) {System.out.println(ex);}
-
โมฆะสาธารณะ closeConnect()
{ลอง{ ftpClient.closeServer();
} จับ (IOException เช่น) {System.out.println (เช่น);}
-
การอัพโหลดโมฆะสาธารณะ ()
{ filename1=findFileName(ชื่อไฟล์);
//วิเคราะห์ชื่อไฟล์จากชื่อไฟล์และใช้เป็นชื่อของไฟล์เป้าหมาย ไม่ได้กำหนดวิธีการเฉพาะ
พยายาม {
TelnetOutputStream os=ftpClient.put(ชื่อไฟล์1);
java.io.File file_in=ใหม่ java.io.File(ชื่อไฟล์);
FileInputStream คือ = FileInputStream ใหม่ (file_in);
ไบต์ [] ไบต์ = ไบต์ใหม่ [1024];
อินท์ค;
ในขณะที่ ((c=is.read(ไบต์))!=-1){ os.write(ไบต์,0,c);
is.close(); os.ปิด();
} catch (IOException เช่น) {System.out.println(ex);}
-
}
ConnectServer() ทำหน้าที่สร้างการเชื่อมต่อกับเซิร์ฟเวอร์ FTP ให้เสร็จสมบูรณ์ ใช้วิธี openServer (เซิร์ฟเวอร์สตริง) ของ FtpClient เพื่อเปิดเซิร์ฟเวอร์ FTP ระยะไกล จากนั้นใช้วิธีการเข้าสู่ระบบ (ผู้ใช้ รหัสผ่าน) ของ FtpClient เพื่อเข้าสู่ระบบเซิร์ฟเวอร์ มีสองวิธีในการเข้าสู่ระบบเซิร์ฟเวอร์ FTP ระยะไกล วิธีหนึ่งคือการเข้าสู่ระบบในฐานะผู้ใช้ที่ลงทะเบียน และอีกวิธีหนึ่งคือการเข้าสู่ระบบโดยไม่ระบุชื่อ แบบแรกกำหนดให้ผู้ใช้ลงทะเบียนเป็นไคลเอนต์ของเซิร์ฟเวอร์ก่อน เซิร์ฟเวอร์จะให้บัญชีเข้าสู่ระบบและรหัสผ่านแก่ผู้ใช้ และเชื่อมต่อกับเซิร์ฟเวอร์ตามบัญชีและรหัสผ่าน อย่างหลังกำหนดให้ผู้ใช้ใช้ชื่อผู้ใช้พิเศษ "น่ารำคาญ" และ "แขก" โดยไม่ต้องลงทะเบียนเพื่อจำกัดการเข้าถึงไฟล์สาธารณะบนโฮสต์ระยะไกล ขณะนี้หลายระบบต้องการให้ผู้ใช้ใช้ที่อยู่อีเมลเป็นรหัสผ่าน เพื่อวัตถุประสงค์ด้านความปลอดภัย โดยทั่วไปโฮสต์ FTP ที่ไม่เปิดเผยตัวตนส่วนใหญ่จะอนุญาตให้ผู้ใช้ระยะไกลดาวน์โหลดไฟล์เท่านั้น แต่จะไม่อัปโหลด ทั้งนี้จะขึ้นอยู่กับการตั้งค่าของเซิร์ฟเวอร์ FTP ผู้ใช้สามารถเลือกใช้งานได้ 2 วิธีตามเงื่อนไขจริง หลังจากเข้าสู่ระบบแล้ว ให้ใช้วิธี binary() ของ FtpClient เพื่อเริ่มต้นโหมดการส่งข้อมูลเป็นโหมดไบต์ upload() ทำหน้าที่อัพโหลดไฟล์ให้สมบูรณ์ สร้างสตรีมอินพุตไฟล์ FileInputStream ของไฟล์ต้นฉบับ เขียนสตรีมอินพุตลงในอาร์เรย์ไบต์ และใช้วิธีการเขียนของ TelnetOutputStream เพื่อเขียนข้อมูลในอาร์เรย์ไบต์ไปยังลิงก์เครือข่าย เนื่องจาก TelnetOutputStream เปิดไฟล์บนเซิร์ฟเวอร์ FTP ข้อมูลจะถูกเขียนไปยังไฟล์เป้าหมาย ซึ่งจะทำให้การอัพโหลดไฟล์เสร็จสมบูรณ์ closeConnect() จำเป็นต้องตัดการเชื่อมต่อจากเซิร์ฟเวอร์
ข้างต้นเป็นเพียงขั้นตอนการอัพโหลดไฟล์เดียว หากมีหลายไฟล์ กระบวนการอัพโหลดนี้สามารถเรียกได้หลายครั้ง จากสองวิธีข้างต้น เราจะเห็นว่าการใช้โปรโตคอล FTP เพื่ออัปโหลดหลายไฟล์นั้นค่อนข้างง่ายและใช้งานง่าย โดยทั่วไปการใช้โปรโตคอล FTP เพื่ออัปโหลดไฟล์จะเป็นโปรแกรมฝั่งไคลเอ็นต์ และการตั้งค่าความปลอดภัยฝั่งเซิร์ฟเวอร์จะซับซ้อนกว่า ในขณะที่การใช้โปรโตคอล HTTP เพื่ออัปโหลดไฟล์จะเป็นแอปพลิเคชันฝั่งเซิร์ฟเวอร์ และการตั้งค่าความปลอดภัยจะค่อนข้างง่าย . และจากการทดสอบพบว่าวิธีการอัปโหลด FTP นั้นเร็วกว่าวิธีอัปโหลด HTTP หลายสิบหรือหลายร้อยเท่าเมื่อส่งไฟล์ขนาดใหญ่ แต่จะช้ากว่าวิธีอัปโหลด HTTP เล็กน้อยเมื่อส่งไฟล์ที่มีขนาดเล็กกว่า 1M ดังนั้นวิธีการส่งข้อมูลทั้งสองวิธีจึงมีข้อดีในตัวเอง ผู้อ่านควรปฏิบัติตามสถานการณ์ของตนเอง หากคุณมีคำถามหรือต้องการซอร์สโค้ดของส่วนอื่นๆ โปรดติดต่อฉัน!