Ohne Bibliotheken von Drittanbietern wird ein minimaler HTTP-Datei-Download-Client ausschließlich auf Java Socket implementiert. Eine vollständige Demonstration der Implementierung des HTTP -Anforderungsheaders zum Herunterladen von Dateien über Socket, um ein HTTP -Antwort (Antwortheader, Antwortkörper) aus Socket zu senden und Dateiinhalte zu analysieren und zu speichern. So erkennen Sie die UI -Aktualisierung durch Swingwork, um den Download -Fortschritt in Echtzeit anzuzeigen.
Schauen Sie sich zunächst den UI -Teil an:
【Download hinzufügen】 Schaltfläche:
Klicken Sie auf das Popup-URL-Eingangsfeld. Nachdem der Benutzer die Datei -URL in das Eingabefeld herunterladen wollte, klicken Sie auf die Schaltfläche [OK], um zu starten.
herunterladen
【Vervollständigen Sie vollständig】 Taste:
Löschen Sie alle heruntergeladenen Dateienliste
Der Datei -Download -Status ist in die folgenden Typen unterteilt:
Paket com.gloomyfish.socket.tutorial.http.Download; public enum downloadStatus {not_started, in_process, abgeschlossen, Fehler} Der UI -Teil wird hauptsächlich mit Schwungkomponenten durchgeführt. Klicken Sie auf [Download hinzufügen], um den Code wie folgt auszuführen:
endgültig jDialog Dialog = new JDialog (this, "Dateiverbindung hinzufügen", true); dialog.getContentPane (). setLayout (new BorderLayout ()); // Dialog.Setsize (neue Dimension (400.200)); endgültige urlfilepanel panel = new urlFilepanel (); panel.setUplistener (new ActionListener () {@Override public void actionPerformed (actionEvent e) {if ("ok" .Equals (E.GetActionCommand ()) {if (Panel Tablemodel.getData (). dialog.getContentPane (). Add (Panel, BorderLayout.Center); Dialog.pack (); Zentrum (Dialog); Dialog.setVisible (True); Der von der Schaltfläche [Clear Complete] ausgeführte Code lautet wie folgt:
private void clearDownload () {list <DownloadDetailStatusinfomodel> downloadedList = new ArrayList <DownloadDetailStatusinfomodel> (); für (downloadDetailStatusinfomodel filestatus: Tablemodel.getData ()) {if (filestatus.getStatus (). toString (). Equals (downloadStatus.comPleted.toString ()) {downloadedList.add (filestatusus); }} Tablemodel.getData (). removeall (DownloadedList); Refreshui (); } Der Code für die Zentrierung der JFRame -Komponente lautet wie folgt:
public static void Center (Fenster w) {Dimension us = w.getSize (); Dimension sie = Toolkit.getDefaulttoolkit (). GetCreenSize (); int newx = (sie.width - US.Width) / 2; int newy = (sie.height - US.Height) / 2; W.SetLocation (Newx, Newy); }HTTP -Protokoll -Implementierungsteil:
Übersicht: Grundstruktur und Erläuterung des HTTP -Anforderungsheaders und entsprechenden Headerpakete
HTTP -Anfrage: Ein Standard -HTTP -Anforderungspaket wie z. B.
Es kann mehrere Anforderungsüberschriften geben, und der Nachrichtenkörper kann keine sein, was nicht erforderlich ist. Das Format der Anforderungszeile lautet wie folgt:
Request-Line = Methode SP Request-URI SPHTTP-Version CRLF gibt ein Beispiel wie folgt:
Request-line = Get http://www.w3.org/pub/www/theproject.htmlhttp/1.1/r/n
Wenn SP Leerzeichen repräsentiert, repräsentiert CRLF die Return -Line -Brennungen/r/n
Wenn Sie eine Datei hochladen möchten, füllen Sie die Daten in den Nachrichtenkörper aus. Senden Sie einen
Eine einfache HTTP -Anforderungsnachricht lautet wie folgt:
HTTP -Antwort: Eine Standard -HTTP -Antwortnachricht lautet wie folgt
Das erste, was Sie erhalten, ist die Statuszeile. Das Format lautet wie folgt:
Status-Line = Http-Version SP ST STATUS-CODESP AUSBRAUCH-PRLF CRLF, Ein einfaches Beispiel für eine Statuszeile ist wie folgt: Statuszeile = HTTP/1.1 200 OK Im Allgemeinen ist der Favorit für jeden Status-Code, der Ihnen viele Eingabeaufforderungen gibt. Das Wichtigste, um eine Datei herunterzuladen, ist die Überprüfung der Inhaltslänge und des Inhaltstyps im HTTP-Antwortheader.
Die Länge und Art der Datei werden separat deklariert. Andere, wie z. B. Akzeptieren, repräsentieren, wie viele Bytes akzeptiert werden. Möglicherweise in Multi-Thread-Downloads verwendet. Nachdem wir das Paketformat der HTTP -Anforderung und -antwort verstanden haben, können wir den Inhalt im Paketformat über Socket, Senden und Lesen von HTTP -Anforderungen und -antwort analysieren. Spezifische Schritte
wie folgt:
1. Erstellen Sie eine Socket -Verbindung basierend auf der vom Benutzer eingegebenen Datei -URL
URL URL = new URL (FileInfo.getFileurl ()); String host = 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 ("Datei uri =" + url.getFile ()); // Socket erstellen und mit dem Erstellen des Anforderungsleitungs -Socket Socket = New Socket () konstruieren; SocketAddress -Adresse = new inetsocketaddress (Host, Port); Socket.Connect (Adresse); Die URL -Klasse wird verwendet, um die vom Benutzer eingegebene URL -Zeichenfolge in eine URL zu verwandeln, die leichter analysiert ist.
2. Konstrukt HTTP -Anforderungen konstruieren
BufferedWriter bufferedWriter = neuer BufferedWriter (neuer Ausgangsstreamwriter (Socket.GetOutputStream (), "UTF8")); String RequestStr = "get" + url.getFile () + "http/1.1/r/n"; // Anforderungszeile // Konstruieren Sie den Anforderungsheader - Konstruieren Sie den HTTP -Anforderungsheader (Anfrage -Header) String hostheader = "Host:" + host + "/r/n"; String accepTheader = "Akzeptieren: text/html, application/xhtml+xml, application/xml; q = 0,9,*/*; q = 0,8/r/n"; String charSetheader = "Akzeptieren-Charset: GBK, UTF-8; q = 0,7,*; Q = 0,3/r/n"; String LanguageHeader = "Akzeptieren Sie Sprache: ZH-CN, ZH; Q = 0,8/R/N"; String keedeHeader = "Verbindung: Close/r/n";
3. Senden Sie die HTTP -Anfrage
// HTTP -Anforderung BufferedWriter.Write (RequestSTR) senden; bufferedWriter.write (Hostheader); bufferedWriter.write (accepTheader); bufferedWriter.write (CharSetheader); bufferedWriter.Write (Sprachkopfer); bufferedWriter.write (Keepheader); bufferedWriter.write ("/r/n"); // Anfrage Header -Nachricht Senden des Endflags BufferedWriter.flush (); 4. Akzeptieren Sie die HTTP -Antwort und analysieren Sie Inhalte und schreiben Sie in die erstellte Datei
// Bereiten Sie sich darauf vor, HTTP -Antwortheader zu akzeptieren und CustomDatainputStream input = new CustomDatainputStream (Socket.GetInputStream ()); Datei myFile = neue Datei (FileInfo.getStorElocation () + Datei.Separator + FileInfo.getFileName ()); String content = null; HttPresponseHeaderParser responseHeader = new httPresponseHeHeHeHeerParser (); PufufferedOutputStream output = new bufferedOutputStream (neuer FileOutputStream (myFile)); boolean hasdata = false; while ((content = input.readhttPesponSheaderline ())! responseHeader.adDesponseHeaderline (Inhalt); if (content.length () == 0) {HasData = true; } if (hasData) {int TotalByTes = responseHeader.getFilelength (); if (TotalBytes == 0) brechen; // Keine Antwortkörper und Daten int offset = 0; byte [] mydata = null; if (TotalBytes> = 2048) {mydata = new byte [2048]; } else {mydata = new Byte [TotalBytes]; } int numofBytes = 0; while ((numofBytes = input.read (mydata, 0, mydata.length))> 0 && offset <TotalBytes) {offset += numofBytes; float p = ((float) offset) / ((float) TotalBytes) * 100,0f; if (offset> TotalBytes) {numofBytes = numofBytes + TotalBytes - Offset; p = 100,0f; } output.write (mydata, 0, numofBytes); updatestatus (p); } HasData = false; brechen; }} Der einfache HTTP -Antwort -Header -Parsing -Klasse HTTPResponseHeaderParser -Code lautet wie folgt:
Paket com.gloomyfish.socket.tutorial.http.Download; import Java.util.hashMap; import Java.util.map; /** * Es kann Entity -Header, Antwortkopf * und Antwortzeile <Statuscode, Zeichenset, ect ...> * Siehe RFC2616 analysieren. Für HTTP -Antwort -Header finden Sie das RFC -Dokument, das ausführlich beschrieben wird! ! */ public class httPresponseHeHeHeHeerParser {public Final static String content_length = "Content-Length"; public Final Static String content_type = "Content-Type"; öffentliche endgültige statische String Accept_Ranges = "Accetp-Ranges"; private map <String, String> Headermap; public httPresponseHeaderParser () {Headermap = new HashMap <String, String> (); }/** * <p> das Antwortpaar des Antwort -Header -Schlüsselwerts </p> * @param responseHeaderline */public void addResponseHeader (String responseHeaderline) {if (responseheaderline.contains (":")) {String [] KeyValue = responseHeader.SPLIT (":"); if (KeyValue [0] .EqualSignoreCase (content_length)) {Headermap.put (content_length, KeyValue [1]); } else if (KeyValue [0] .EqualSignoreCase (content_type)) {Headermap.put (content_type, keyValue [1]); } else {Headermap.put (KeyValue [0], KeyValue [1]); }}} public int getFilelength () {if (Headermap.get (content_length) == null) {return 0; } return Integer.parseInt (HeaderMap.get (content_length)); } public String getFileType () {return Headermap.get (content_type); } public map <String, String> getAllHeaders () {return Headermap; }}Das obige dreht sich alles um diesen Artikel. Ich hoffe, dass es für alle hilfreich sein wird, Java -Programme zu lernen.