หากไม่มีไลบรารีของบุคคลที่สามไคลเอนต์ดาวน์โหลดไฟล์ HTTP ที่น้อยที่สุดจะถูกนำมาใช้ทั้งหมดตามซ็อกเก็ต Java การสาธิตอย่างสมบูรณ์เกี่ยวกับวิธีการใช้ส่วนหัวคำขอ HTTP สำหรับการดาวน์โหลดไฟล์ผ่านซ็อกเก็ตเพื่อส่งแพ็คเก็ตตอบสนอง HTTP (ส่วนหัวตอบกลับ, การตอบสนอง) แพ็คเก็ตจากซ็อกเก็ตและแยกวิเคราะห์และบันทึกเนื้อหาไฟล์ วิธีตระหนักถึงการรีเฟรช UI ผ่านการแกว่งเพื่อแสดงความคืบหน้าการดาวน์โหลดแบบเรียลไทม์
ก่อนอื่นดูส่วน UI:
【เพิ่มดาวน์โหลด】ปุ่ม:
คลิกกล่องอินพุต URL แบบป๊อปอัพ หลังจากผู้ใช้ต้องการดาวน์โหลด URL ไฟล์ไปยังกล่องอินพุตให้คลิกปุ่ม [OK] เพื่อเริ่มต้น
การดาวน์โหลด
【ล้างปุ่มเสร็จสมบูรณ์】:
ล้างรายการไฟล์ที่ดาวน์โหลดทั้งหมด
สถานะการดาวน์โหลดไฟล์แบ่งออกเป็นประเภทต่อไปนี้:
แพ็คเกจ com.gloomyfish.socket.tutorial.http.download; public enum downloadstatus {not_started, in_process, เสร็จสมบูรณ์, ข้อผิดพลาด} ส่วน UI ส่วนใหญ่ทำโดยใช้ส่วนประกอบสวิง คลิก [เพิ่มดาวน์โหลด] เพื่อเรียกใช้รหัสดังนี้:
กล่องโต้ตอบ jdialog สุดท้าย = new JDialog (นี่ "เพิ่มลิงค์ไฟล์", จริง); Dialog.getContentPane (). SetLayout (New BorderLayout ()); // dialog.setsize (มิติใหม่ (400,200)); ขั้นสุดท้าย URLFilePanel Panel = ใหม่ urlFilePanel (); Panel.SetUpListener (ใหม่ actionListener () {@Override โมฆะสาธารณะ ActionPerformed (ActionEvent E) {ถ้า ("OK" .Equals (e.getActionCommand ())) {ถ้า (panel.validateInput () {downloadDetailStatusInfomodel = new Downloaddetailail Tablemodel.getData (). เพิ่ม (ข้อมูล); Dialog.getContentPane (). เพิ่ม (แผง, BorderLayout.Center); Dialog.pack (); ศูนย์ (กล่องโต้ตอบ); Dialog.setVisible (จริง); รหัสที่ดำเนินการโดยปุ่ม [Clear Complete] มีดังนี้:
Void Private Cleardownloaded () {list <downloadDetailStatusInfomodel> downloadEdList = arrayList ใหม่ <lowwlowdDetailStatusInfomodel> (); สำหรับ (downloaddetailstatusinfomodel filestatus: tablemodel.getData ()) {ถ้า (filestatus.getStatus (). toString (). เท่ากับ (downloadstatus.completed.tostring ())) }} tableModel.getData (). RemoveAll (ดาวน์โหลดรายการ); refreshui (); - รหัสสำหรับการจัดศูนย์องค์ประกอบ JFrame มีดังนี้:
ศูนย์โมฆะคงที่สาธารณะ (หน้าต่าง W) {Dimension US = W.GetSize (); มิติพวกเขา = toolkit.getDefaultToolkit (). getScreensize (); int newx = (พวกเขา. width - us.width) / 2; int newy = (พวกเขา height - us.height) / 2; W.SetLocation (newx, newy); -ส่วนการใช้งานโปรโตคอล HTTP:
ภาพรวม: โครงสร้างพื้นฐานและคำอธิบายของส่วนหัวคำขอ HTTP และแพ็คเก็ตส่วนหัวที่เกี่ยวข้อง
คำขอ http: แพ็คเก็ตคำขอ HTTP มาตรฐานเช่น
อาจมีส่วนหัวคำขอหลายส่วนและไม่มีใครเป็นคนที่ไม่จำเป็นซึ่งไม่จำเป็น รูปแบบของสายคำขอมีดังนี้:
request-line = method sp request-uri sphttp-version crlf ให้ตัวอย่างดังนี้:
request-line = รับ http://www.w3.org/pub/www/theproject.htmlhttp/1.1/r/n
ในกรณีที่ SP แสดงช่องว่าง CRLF แสดงถึงการแบ่งสายการขนส่ง/r/n
เมื่อคุณต้องการอัปโหลดไฟล์ให้ใช้โพสต์เพื่อกรอกข้อมูลลงในร่างกายข้อความ ส่งหนึ่ง
ข้อความคำขอ HTTP อย่างง่ายมีดังนี้:
การตอบสนอง http: ข้อความตอบกลับ HTTP มาตรฐานมีดังนี้
สิ่งแรกที่คุณได้รับคือบรรทัดสถานะรูปแบบของมันมีดังนี้:
สถานะ-บรรทัด = HTTP-version SP สถานะ-วลีเหตุผล CRLF, ตัวอย่างง่ายๆของบรรทัดสถานะมีดังนี้: สถานะ-บรรทัด = HTTP/1.1 200 ตกลงโดยทั่วไปทุกคนโปรดปรานคือรหัสสถานะซึ่งจะให้คำแนะนำบ่อยที่สุดคือรหัสสถานะเช่น 404, 500 ฯลฯ สิ่งที่สำคัญที่สุดในการดาวน์โหลดไฟล์คือการตรวจสอบความยาวเนื้อหาและประเภทเนื้อหาในส่วนหัวการตอบกลับ HTTP
ความยาวและประเภทของไฟล์ถูกประกาศแยกกัน คนอื่น ๆ เช่นการยอมรับช่วงแสดงจำนวนที่ยอมรับได้กี่ไบต์ อาจใช้ในการดาวน์โหลดแบบมัลติเธรด หลังจากทำความเข้าใจรูปแบบแพ็คเก็ตของคำขอและการตอบสนอง HTTP เราสามารถแยกวิเคราะห์เนื้อหาในรูปแบบแพ็คเก็ตผ่านซ็อกเก็ตส่งและอ่านคำขอและการตอบกลับ HTTP ขั้นตอนเฉพาะ
ดังนี้:
1. สร้างการเชื่อมต่อซ็อกเก็ตตาม URL ไฟล์ที่ป้อนโดยผู้ใช้
url url = url ใหม่ (fileinfo.getFileUrl ()); สตริงโฮสต์ = url.getHost (); int port = (url.getport () == -1)? url.getDefaultport (): url.getport (); System.out.println ("ชื่อโฮสต์ =" + โฮสต์); System.out.println ("พอร์ต =" + พอร์ต); System.out.println ("ไฟล์ uri =" + url.getFile ()); // สร้างซ็อกเก็ตและเริ่มสร้างซ็อกเก็ตซ็อกเก็ตสายคำขอ = ซ็อกเก็ตใหม่ (); SocketAddress address = ใหม่ inetSocketAddress (โฮสต์, พอร์ต); Socket.Connect (ที่อยู่); คลาส URL ใช้เพื่อเปลี่ยนสตริง URL ที่ป้อนโดยผู้ใช้เป็น URL ที่แยกวิเคราะห์ได้ง่ายขึ้น
2. สร้างคำขอ HTTP
bufferedWriter bufferedWriter = new BufferedWriter (New OutputStreamWriter (Socket.GetOutputStream (), "UTF8")); string requestStr = "get" + url.getFile () + "http/1.1/r/n"; // คำขอบรรทัด // สร้างส่วนหัวคำขอ - สร้างส่วนหัวคำขอ HTTP (ส่วนหัวคำขอ) สตริง hosttheader = "โฮสต์:" + โฮสต์ + "/r/n"; string acceptheader = "ยอมรับ: ข้อความ/html, แอปพลิเคชัน/xhtml+xml, application/xml; q = 0.9,*/*; q = 0.8/r/n"; String Charsetheader = "Accept-Charset: GBK, UTF-8; q = 0.7,*; q = 0.3/r/n"; String LanguageHeader = "Accept-Language: ZH-CN, ZH; q = 0.8/r/n"; String Keepheader = "การเชื่อมต่อ: ปิด/r/n";
3. ส่งคำขอ HTTP
// ส่ง HTTP Request BufferedWriter.write (RequestStr); BufferedWriter.write (Hostheader); bufferedWriter.write (acceptheader); bufferedWriter.write (charsetheader); bufferedWriter.write (หัวหน้าภาษา); bufferedWriter.write (Keepheader); bufferedWriter.write ("/r/n"); // คำขอส่วนหัวคำขอส่ง flag end bufferedWriter.flush (); 4. ยอมรับการตอบกลับ HTTP และแยกวิเคราะห์เนื้อหาและเขียนไปยังไฟล์ที่สร้างขึ้น
// เตรียมที่จะยอมรับส่วนหัวการตอบกลับ HTTP และแยกวิเคราะห์ CustomDatainputStream อินพุต = ใหม่ CustomDatainputStream (Socket.GetInputStream ()); ไฟล์ myfile = ไฟล์ใหม่ (fileinfo.getStorElocation () + file.Separator + fileinfo.getFilename ()); เนื้อหาสตริง = null; httpresponseHeaderParser ResponseHeader = ใหม่ httpresponseHeaderParser (); bufferedOutputStream output = ใหม่ bufferedOutputStream (ใหม่ fileOutputStream (myFile)); บูลีน hasdata = false; ในขณะที่ ((content = input.readhttpresponseHeaderLine ())! = null) {system.out.println ("ผู้ติดต่อส่วนหัวตอบกลับ ->>" + เนื้อหา); ResponseHeader.addresponseHeaderLine (เนื้อหา); if (content.length () == 0) {hasdata = true; } if (hasdata) {int totalBytes = responceHeader.getFileLength (); if (TotalBytes == 0) BREAK; // ไม่มีการตอบสนองของร่างกายและข้อมูล int ออฟเซ็ต = 0; ไบต์ [] myData = null; if (totalBytes> = 2048) {myData = byte ใหม่ [2048]; } else {myData = ไบต์ใหม่ [TotalBytes]; } int numofbytes = 0; ในขณะที่ ((numofbytes = input.read (myData, 0, myData.length))> 0 && ออฟเซ็ต <TotalBytes) {Offset += numofbytes; float p = ((ลอย) ออฟเซ็ต) / ((ลอย) TotalBytes) * 100.0f; if (Offset> TotalBytes) {numofByTes = numofByTes + TotalBytes - Offset; p = 100.0f; } output.write (mydata, 0, numofbytes); updatestatus (P); } hasdata = false; หยุดพัก; - ส่วนหัวการตอบกลับ HTTP แบบง่าย ๆ การแยกวิเคราะห์คลาส HTTPRESSPONSEHEADERPARSER เป็นดังนี้:
แพ็คเกจ com.gloomyfish.socket.tutorial.http.download; นำเข้า java.util.hashmap; นำเข้า java.util.map; /** * สามารถแยกวิเคราะห์ส่วนหัวเอนทิตี, หัวตอบกลับ * และสายการตอบกลับ <รหัสสถานะ, charset, ect ... > * อ้างถึง RFC2616 สำหรับส่วนหัวการตอบกลับ HTTP โปรดดูเอกสาร RFC ซึ่งอธิบายไว้ในรายละเอียด! - */ คลาสสาธารณะ httpresponseHeaderParser {สตริงคงสุดท้ายสาธารณะสุดท้าย content_length = "ความยาวเนื้อหา"; สตริงคงที่สาธารณะสุดท้าย content_type = "เนื้อหาประเภท"; สตริงคงที่สาธารณะสุดท้าย accept_ranges = "accetp-ranges"; แผนที่ส่วนตัว <สตริงสตริง> headermap; public httpresponseHeaderParser () {headerMap = new hashmap <string, string> (); }/** * <p> รับคู่คีย์การตอบกลับคู่คู่ </p> * @param ResponseHeaderLine */โมฆะสาธารณะ addResponseHeaderLine (สตริง ResponseHeaderLine) {ถ้า (ResponseHeaderLine.contains (":")) if (keyValue [0] .EqualSIGNORECASE (content_length)) {headerMap.put (content_length, keyValue [1]); } อื่นถ้า (keyValue [0] .equalsignorecase (content_type)) {headerMap.put (content_type, keyValue [1]); } else {headerMap.put (keyValue [0], keyValue [1]); }}} public int getFileLength () {ถ้า (headerMap.get (content_length) == null) {return 0; } return integer.parseint (headermap.get (content_length)); } สตริงสาธารณะ getFileType () {return headermap.get (content_type); } แผนที่สาธารณะ <สตริงสตริง> getAllheaders () {return headermap; -ข้างต้นเป็นเรื่องเกี่ยวกับบทความนี้ฉันหวังว่ามันจะเป็นประโยชน์สำหรับทุกคนในการเรียนรู้การเขียนโปรแกรม Java