Sans bibliothèques tierces, un client de téléchargement de fichiers HTTP minimal est implémenté entièrement basé sur Java Socket. Une démonstration complète de la façon d'implémenter l'en-tête de demande HTTP pour télécharger des fichiers via Socket pour envoyer un paquet de réponse HTTP (en-tête de réponse, corps de réponse) à partir du socket et de l'ajustement et enregistrer le contenu des fichiers. Comment réaliser une actualisation de l'interface utilisateur via Swingwork pour afficher les progrès de téléchargement en temps réel.
Regardez d'abord la partie d'interface utilisateur:
【Ajouter le téléchargement】 bouton:
Cliquez sur la zone d'entrée URL pop-up. Une fois que l'utilisateur souhaite télécharger l'URL du fichier dans la zone d'entrée, cliquez sur le bouton [OK] pour démarrer.
télécharger
【Effacer le bouton complet】:
Effacer la liste des fichiers téléchargés
Le statut de téléchargement de fichiers est divisé en les types suivants:
package com.gloomyfish.socket.tutorial.http.Download; Public Enum DownloadStatus {not_started, in_process, terminé, erreur} La pièce d'interface utilisateur se fait principalement en utilisant des composants de swing. Cliquez sur [Ajouter un téléchargement] pour exécuter le code comme suit:
dialogue final jdialog = new JDialog (this, "Ajouter un lien de fichier", true); Dialog.getContentPane (). setLayout (new BorderLayout ()); // Dialog.SetSize (nouvelle dimension (400,200)); Panneau URLFilePanel final = nouveau UrlFilePanel (); PANNEL.SetUpListener (new ActionListener () {@Override public void ActionPerformed (ActionEvent e) {if ("ok" .equals (e.getActionCommand ())) {if (Panel.ValidateInput ()) {téléchargementDetailstatusInfomodel data = new DownloadDetAtatusInfoModel (Panel.getvalidfileUrl ()); TableMoDel.getData (). Dialog.getContentPane (). Add (panneau, borderLayout.Center); Dialog.pack (); Centre (dialogue); Dialog.setVisible (true); Le code exécuté par le bouton [Clear Complete] est le suivant:
private void cleardownloaded () {list <downloadDetailstatusInfomodel> téléchargéListList = new ArrayList <téléchargementDetailStatusInfomodel> (); for (downloadDetailstatusInfomodel FileStatus: TableModel.getData ()) {if (FileStatus.getStatus (). ToString (). }} TableModel.getData (). RemoveAll (téléchargements); refreshui (); } Le code pour centrer le composant JFrame est le suivant:
Public Static Void Center (Window W) {Dimension US = w.getSize (); Dimension Them = Toolkit.getDefaultToolkit (). GetScreensize (); int newx = (Them.Width - us.width) / 2; int newy = (Them.Height - us.height) / 2; w.setLocation (newx, newy); }Partie de mise en œuvre du protocole HTTP:
Présentation: structure de base et explication de l'en-tête de demande HTTP et des paquets d'en-tête correspondants
Demande HTTP: un paquet de demande HTTP standard tel que
Il peut y avoir plusieurs en-têtes de demande, et le corps de message ne peut en être aucun, ce qui n'est pas nécessaire. Le format de la ligne de demande est le suivant:
Request-line = Method SP request-uri sphttp-version crlf donne un exemple comme suit:
Request-line = get http://www.w3.org/pub/www/theproject.htmlhttp/1.1/r/n
Lorsque SP représente les espaces, le CRLF représente les pauses de la ligne de retour du chariot / R / N
Lorsque vous souhaitez télécharger un fichier, utilisez la publication pour remplir les données dans le corps de message. Envoyer un
Un simple message de demande HTTP est le suivant:
Réponse HTTP: Un message de réponse HTTP standard est le suivant
La première chose que vous obtenez est la ligne d'état, son format est le suivant:
Statut-line = Http-Version SP Status CoDesp Reason-Phrase CRLF, Un exemple simple de ligne de statut est le suivant: Status-Line = HTTP / 1.1 200 Généralement, le favori de tout le monde est le code d'état qui vous donnera de nombreuses invites, les plus courants sont des codes d'état tels que 404, 500, etc. La chose la plus importante à télécharger un fichier est de vérifier le contenu-longueur et le type de contenu dans l'en-tête de réponse HTTP.
La longueur et le type de fichier sont déclarés séparément. D'autres, tels que les gammes d'accept, représentent combien pour combien d'octets sont acceptés. Peut-être utilisé dans les téléchargements multi-thread. Après avoir compris le format de paquet de la demande et de la réponse HTTP, nous pouvons analyser le contenu dans le format de paquet via Socket, envoyer et lire la demande et la réponse HTTP. Étapes spécifiques
comme suit:
1. Établissez une connexion de socket en fonction de l'URL de fichier entrée par l'utilisateur
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 ("File uri =" + url.getFile ()); // Créer une prise et commencer à construire la socket de requête socket socket = new socket (); SocketAddress Adresse = new IneTSocketAddress (hôte, port); socket.connect (adresse); La classe URL est utilisée pour transformer la chaîne d'URL entrée par l'utilisateur en une URL plus facile à analyser.
2. Construire les demandes HTTP
BufferedWriter BufferedWriter = new BufferedWriter (new OutputStreamWriter (socket.getOutputStream (), "UTF8")); String requeststr = "get" + url.getFile () + "http / 1.1 / r / n"; // Ligne de demande // Construisez l'en-tête de demande - Construisez l'en-tête de demande HTTP (en-tête de demande) String hostheader = "host:" + host + "/ r / n"; String acceptHeader = "accepter: text / html, application / 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 = "Connection: close / r / n";
3. Envoyez la demande HTTP
// Envoi de la demande HTTP BufferedWriter.Write (Requeststr); BufferedWriter.Write (Hostheader); BufferedWriter.Write (AcceptHeader); BufferedWriter.Write (Charsetheader); BufferedWriter.Write (LanguageHeader); BufferedWriter.Write (KeepHeader); BufferedWriter.Write ("/ R / N"); // Demande le message d'en-tête Envoi de l'indicateur de fin BufferedWriter.Flush (); 4. Acceptez la réponse HTTP et analysez le contenu et écrivez dans le fichier créé
// Préparez-vous à accepter les en-têtes de réponse HTTP et à analyser CustomDatainPutStream Input = new CustomDatAnputStream (socket.getInputStream ()); File myFile = new File (fileInfo.getStoreLocation () + file.separator + fileInfo.getFileName ()); String Content = NULL; HttpResponseHeDederPaSer ResponseHeader = new httpResponseHeaderPaSer (); BufferedOutputStream output = new BufferedOutStream (new FileOutputStream (myFile)); booléen hasdata = false; while ((content = input.readHttpResponseHeDeNerline ())! = null) {System.out.println ("En-tête de réponse Contact - >>" + Contenu); ResponseHeader.AddreSponseHeaderLine (contenu); if (content.length () == 0) {Hasdata = true; } if (hasdata) {int totalBytes = réponse. if (TotalBytes == 0) Break; // Aucun corps de réponse et données int offset = 0; octet [] mydata = null; if (totalBytes> = 2048) {myData = new octet [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; casser; }} Le code d'analyse de l'en-tête de réponse HTTP simple de la classe HTTPResponseHeaderParser est le suivant:
package com.gloomyfish.socket.tutorial.http.Download; import java.util.hashmap; importation java.util.map; / ** * Il peut analyser l'en-tête d'entité, la tête de réponse * et la ligne de réponse <code d'état, charse, ect ...> * Reportez-vous à RFC2616. Pour les en-têtes de réponse HTTP, veuillez consulter le document RFC, qui est décrit en détail! ! * / public class httpResponseHeDerParser {public final static String content_length = "contenu-lingth"; public final static String contenu_type = "Content-Type"; Public Final Static String accepte_Ranges = "Accetp-Ranges"; Carte privée <String, String> HeaderMap; public httpResponseHeDerParser () {HeaderMap = new HashMap <String, String> (); } / ** * <p> Obtenez la paire de valeurs de clé d'en-tête de réponse </p> * @Param ResponseHeaderLine * / public void AddRaSesponseHeaderLine (String ResponseHeaderLine) {if (ResponseHeaderLine.Contains (":")) {String [] keyValue = ResponseHeaderLine.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> getAllHelers () {return heanermap; }}Ce qui précède concerne cet article, j'espère qu'il sera utile pour tout le monde d'apprendre la programmation Java.