بدون أي مكتبات طرف ثالث ، يتم تنفيذ عميل تنزيل ملف HTTP الحد الأدنى استنادًا إلى Socket Java. عرض كامل لكيفية تنفيذ رأس طلب HTTP لتنزيل الملفات من خلال Socket لإرسال حزمة استجابة HTTP (رأس الاستجابة ، وجسم الاستجابة) من Socket و Parse وحفظ محتويات الملف. كيفية تحقيق تحديث واجهة المستخدم من خلال الأرجوحة لعرض التقدم في الوقت الحقيقي.
انظر أولاً إلى جزء واجهة المستخدم:
【أضف تنزيل】 الزر:
انقر فوق مربع إدخال عنوان URL المنبثق. بعد أن يريد المستخدم تنزيل عنوان URL للملف إلى مربع الإدخال ، انقر فوق الزر [OK] للبدء.
تحميل
【قم بمسح الزر الكامل】:
امسح جميع قائمة الملفات التي تم تنزيلها
يتم تقسيم حالة تنزيل الملف إلى الأنواع التالية:
حزمة com.gloomyfish.socket.tutorial.http.download ؛ التعداد العام downloadStatus {not_started ، in_process ، مكتمل ، خطأ} يتم إجراء جزء واجهة المستخدم بشكل أساسي باستخدام مكونات التأرجح. انقر فوق [إضافة تنزيل] لتنفيذ الرمز على النحو التالي:
مربع الحوار JDialog النهائي = new jdialog (هذا ، "إضافة ملف الملف" ، صحيح) ؛ Dialog.getContentPane (). setLayout (New BorderLayout ()) ؛ // dialog.Setsize (Dimension New (400،200)) ؛ لوحة urlfilepanel النهائية = urlfilepanel () جديد ؛ panel.setuplistener (new ActionListener () {Override public void actionperformed (ActionEvent e) {if ("ok" .equals ( TableModel.getData. Dialog.getContentPane (). Add (لوحة ، BorderLayout.Center) ؛ Dialog.pack () ؛ المركز (مربع الحوار) ؛ Dialog.SetVisible (true) ؛ الرمز الذي تم تنفيذه بواسطة الزر [Clear Complete] هو كما يلي:
private void clearDownloaded () {list <downloadDetailStatusinFomodel> downloadedList = جديد arraylist <downloadDetailStatusinFomodel> () ؛ لـ (downloadDetailStatusinFomodel filestatus: tableModel.getData ()) {if (filestatus.getStatus (). toString (). }} tableModel.getData (). removeall (تنزيل قائمة) ؛ refreshui () ؛ } الرمز لتوسيط مكون JFRAME هو كما يلي:
مركز الفراغ الثابت العام (نافذة W) {Dimension US = W.GetSize () ؛ بعدهم = toolkit.getDefaultToolkit (). getScreensize () ؛ int newx = (hear.width - us.width) / 2 ؛ int newy = (لهم. HIEGHT - US.HIGHT) / 2 ؛ W.SetLocation (Newx ، Newy) ؛ }جزء تنفيذ بروتوكول HTTP:
نظرة عامة: الهيكل الأساسي وشرح رأس طلب HTTP وحزم الرأس المقابلة
طلب HTTP: حزمة طلب HTTP قياسية مثل
يمكن أن يكون هناك العديد من رؤوس الطلبات ، ويمكن أن يكون جسم الرسائل لا شيء ، وهو أمر غير ضروري. شكل خط الطلب هو كما يلي:
خط الطلب = الطريقة SP request-uri sphttp-version CRLF يعطي مثالًا على النحو التالي:
request-line = get http://www.w3.org/pub/www/theproject.htmlhtp/1.1/r/n
حيث يمثل SP المساحات ، يمثل CRLF فترات سطر عودة النقل/R/N
عندما ترغب في تحميل ملف ، استخدم POST لملء البيانات في جسم الرسائل. أرسل واحدة
رسالة طلب HTTP بسيطة هي كما يلي:
استجابة HTTP: رسالة استجابة HTTP قياسية هي كما يلي
أول شيء تحصل عليه هو خط الحالة ، تنسيقه على النحو التالي:
خط الحالة = http-version sp sp status-codesp-phrase-phrase crlf ، مثال بسيط على خط الحالة هو كما يلي: خط الحالة = http/1.1 200 ok بشكل عام ، فإن كل شخص مفضل هو رمز الحالة الذي سيعطيك العديد من المطالبات ، والأكثر شيوعًا هي رموز الحالة مثل 404 ، 500 ، وما إلى ذلك. يمكن الرجوع إلى رمز الوضع في التحسين في RFC266. أهم شيء لتنزيل ملف هو التحقق من طول المحتوى ونوع المحتوى في رأس استجابة HTTP.
يتم الإعلان عن طول ونوع الملف بشكل منفصل. يمثل الآخرون ، مثل المقبول ، عدد البايتات التي يتم قبولها. ربما تستخدم في التنزيلات متعددة الخيوط. بعد فهم تنسيق الحزمة لطلب واستجابة HTTP ، يمكننا تحليل المحتوى بتنسيق الحزمة من خلال المقبس ، وإرسال وقراءة طلب HTTP والاستجابة. خطوات محددة
على النحو التالي:
1. إنشاء اتصال مقبس بناءً على عنوان URL للملف الذي أدخله المستخدم
url url = url new (fileInfo.getFileUrl ()) ؛ سلسلة مضيف = url.gethost () ؛ int port = (url.getport () == -1)؟ url.getDefaultPort (): url.getport () ؛ System.out.println ("host name =" + host) ؛ System.out.println ("port =" + port) ؛ System.out.println ("file uri =" + url.getFile ()) ؛ // إنشاء مقبس وابدأ في إنشاء مقبس سطر الطلب = مقبس جديد () ؛ SocketAddress عنوان = جديد inetsocketaddress (مضيف ، منفذ) ؛ Socket.connect (العنوان) ؛ يتم استخدام فئة URL لتحويل سلسلة عنوان URL التي أدخلها المستخدم إلى عنوان URL الذي يسهل تحليله.
2. بناء طلبات HTTP
BufferDwriter BufferedWriter = new BufferedWriter (New OutputStreamWriter (socket.getOutputStream () ، "utf8")) ؛ String requestStR = "GET" + url.getFile () + "http/1.1/r/n" ؛ // request line // إنشاء رأس الطلب - قم ببناء رأس طلب HTTP (رأس طلب) سلسلة HosTheader = "Host:" + Host + "/R/N" ؛ String acceptheader = "قبول: النص/html ، التطبيق/xhtml+xml ، application/xml ؛ q = 0.9 ،*/*؛ q = 0.8/r/n" ؛ String charsetheader = "قبول-charset: gbk ، utf-8 ؛ q = 0.7 ،*؛ q = 0.3/r/n" ؛ String LanguageHeader = "قبول باللغة: ZH-CN ، ZH ؛ Q = 0.8/r/n" ؛ String KeepHeader = "Connection: Close/R/N" ؛
3. أرسل طلب HTTP
// إرسال http request bufferedWriter.write (requestStr) ؛ bufferedWriter.write (Hostheader) ؛ bufferedWriter.write (acceptheader) ؛ bufferedWriter.write (charsetheader) ؛ bufferedWriter.write (languageHeader) ؛ bufferedWriter.write (Keepheader) ؛ bufferedWriter.write ("/r/n") ؛ // طلب رسالة رأس إرسال العلامة نهاية العلم bufferedWriter.flush () ؛ 4. قبول HTTP Response ومحتوى التحليل ، واكتب إلى الملف الذي تم إنشاؤه
// الاستعداد لقبول رؤوس استجابة HTTP و parse customDatainputStream إدخال = جديد customDatainputStream (Socket.getInputStream ()) ؛ file myfile = ملف جديد (fileInfo.getStoreLocation () + file.separator + fileInfo.getFilename ()) ؛ محتوى السلسلة = فارغ ؛ httpresponseHeaderParser ResponseHeader = جديد httpresponseheaderparser () ؛ إخراج BufferEdoutputStream = جديد BufferedOutputStream (FileOutputStream جديد (MyFile)) ؛ منطقية hasdata = false ؛ بينما ((content = input.readhttpresponseHeaderline ())! = null) {system.out.println ("contact application application ->>" + content) ؛ ResponseHeader.addResponseHeaderLine (المحتوى) ؛ if (content.length () == 0) {hasdata = true ؛ } if (hasdata) {int totalBytes = responseHeader.getFilelEllenge () ؛ إذا (totalBytes == 0) استراحة ؛ // لا استجابة هيئة وبيانات int الإزاحة = 0 ؛ بايت [] mydata = null ؛ if (totalBytes> = 2048) {myData = new byte [2048] ؛ } آخر {myData = new byte [totalBytes] ؛ } int numofbytes = 0 ؛ بينما ((numofbytes = input.Read (myData ، 0 ، myData.Length))> 0 && offset <totalBytes) {Offset += numOfByTes ؛ تعويم p = ((تعويم) إزاحة) / ((تعويم) totalBytes) * 100.0f ؛ if (Offset> totalBytes) {numofbytes = numofbytes + totalBytes - Offset ؛ P = 100.0f ؛ } output.write (myData ، 0 ، numofbytes) ؛ updatestatus (p) ؛ } hasdata = false ؛ استراحة؛ }} رمز محلل رأس استجابة HTTP البسيط لفئة HTTPRESSENSEDERPARSER كما يلي:
حزمة com.gloomyfish.socket.tutorial.http.download ؛ استيراد java.util.hashmap ؛ استيراد java.util.map ؛ /** * يمكنه تحليل رأس الكيان ، رأس الاستجابة * وخط الاستجابة <رمز الحالة ، charset ، ECT ...> * راجع RFC2616. بالنسبة لرؤوس استجابة HTTP ، يرجى الاطلاع على وثيقة RFC ، والتي تم وصفها بالتفصيل! ! */ الفئة العامة httpresponseHeaderParser {public final static string content_length = "content-length" ؛ public static String content_type = "content-type" ؛ السلسلة الثابتة النهائية العامة قبول_ها = "accetp-ranges" ؛ خريطة خاصة <string ، string> headermap ؛ httpresponseHeaderParser () {headermap = new hashMap <string ، string> () ؛ }/** * <p> احصل على زوج مفتاح رأس الاستجابة زوج </p> * param reviewHeaderLine */public void addResponseHeaderLine (String reviewHeaderLine) {if (desponseHeaderline.contains (":")) {string [] keyvalue = desponseHeaderline.split (":") ؛ if (keyvalue [0] .equalsInsIgnoreCase (content_length)) {headermap.put (content_length ، keyvalue [1]) ؛ } آخر إذا (keyvalue [0] .equalsInsIgnoreCase (content_type)) {headermap.put (content_type ، keyvalue [1]) ؛ } آخر {headermap.put (keyvalue [0] ، keyvalue [1]) ؛ }}} public int getFiLelLength () {if (headermap.get (content_length) == null) {return 0 ؛ } return integer.parseint (headermap.get (content_length)) ؛ } السلسلة العامة getFileType () {return headermap.get (content_type) ؛ } الخريطة العامة <string ، string> getAllheaders () {return headermap ؛ }}ما سبق هو كل شيء عن هذا المقال ، آمل أن يكون من المفيد للجميع تعلم برمجة Java.