サードパーティのライブラリがないと、最小限のHTTPファイルダウンロードクライアントがJavaソケットに完全に基づいて実装されます。ソケットを介してファイルをダウンロードするためのHTTP要求ヘッダーを実装する方法の完全なデモンストレーションは、ソケットからHTTP応答(応答ヘッダー、応答ボディ)パケットを送信し、ファイルコンテンツを解析および保存します。スイングワークを通じてUIの更新を実現して、ダウンロードの進行状況をリアルタイムで表示する方法。
最初にUIパーツを見てください:
ollowdowndownowダウンロードボタンを追加:
[ポップアップURL入力]ボックスをクリックします。ユーザーが入力ボックスにファイルURLをダウンロードしたら、[OK]ボタンをクリックして起動します。
ダウンロード
clear Clear Complete】ボタン:
ダウンロードされたすべてのファイルリストをクリアします
ファイルのダウンロードステータスは、次のタイプに分割されます。
パッケージcom.gloomyfish.socket.tutorial.http.download; public enum downloadstatus {not_started、in_process、完了、エラー} UI部品は、主にスイングコンポーネントを使用して行われます。 [ダウンロードを追加]をクリックして、次のようにコードを実行します。
final jdialogダイアログ= new jdialog(this、 "add file link"、true); dialog.getContentPane()。setLayout(new borderlayout()); // dialog.setsize(new Dimension(400,200)); final urlfilepanelパネル= new urlfilepanel(); panel.setuplistener(new ActionListener(){@Override public void ActionPerformed(ActionEvent e){if( "ok" .equals(e.getActionCommand())){if(panel.validateInput()){downloaddetailstatusinfomodel data = new downloaddetatusinfomodel() tabledel.getdata() dialog.getContentPane()。add(paner、borderlayout.center); dialog.pack();センター(ダイアログ); dialog.setVisible(true); [Clear Complete]ボタンで実行されたコードは次のとおりです。
private void cleardownloaded(){list <downloaddetailstatusinfomodel> downloadedlist = new arrayList <downloaddetailstatusinfomodel>(); for(downloaddetailstatusinfomodel filestatus:tablemodel.getData()){if(filestatus.getStatus()。toString()。 }} tablemodel.getData()。removeall(downloadedlist); refreshui(); } JFrameコンポーネントを中心にするためのコードは次のとおりです。
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); }HTTPプロトコルの実装パート:
概要:HTTP要求ヘッダーと対応するヘッダーパケットの基本構造と説明
HTTPリクエスト:次のような標準のHTTP要求パケット
複数のリクエストヘッダーが存在する可能性があり、メッセージボディは何もない場合がありますが、これは必要ありません。要求行の形式は次のとおりです。
request-line = method sp request-uri sphttp-version crlfは次のように例を示します。
request-line = get http://www.w3.org/pub/www/theproject.htmlhttp/1.1/r/n
SPがスペースを表すところでは、CRLFはキャリッジリターンラインブレーク/r/nを表します
ファイルをアップロードする場合は、投稿を使用してデータをメッセージボディに入力します。 1つ送信します
簡単なHTTPリクエストメッセージは次のとおりです。
HTTP応答:標準のHTTP応答メッセージは次のとおりです
最初に入手するのはステータスラインで、その形式は次のとおりです。
ステータスライン= http-version sp status-codesp recode-phrase crlf、ステータスラインの簡単な例は次のとおりです。ステータスライン= http/1.1 200 ok一般的に、誰もが多くのプロンプトを提供するステータスコードです。最も一般的なものは404、500などのステータスコードです。ファイルをダウンロードする最も重要なことは、HTTP応答ヘッダーのコンテンツレングスとコンテンツタイプを確認することです。
ファイルの長さとタイプは個別に宣言されます。受け入れ範囲などのその他は、受け入れられているバイト数から数を表しています。おそらくマルチスレッドダウンロードで使用されます。 HTTPリクエストと応答のパケット形式を理解した後、ソケットを介してパケット形式のコンテンツを解析することができます。HTTPリクエストと応答を送信および読み取ります。特定の手順
次のように:
1.ユーザーが入力したファイル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( "file uri =" + url.getFile()); //ソケットを作成し、リクエストラインソケットソケット= new Socket()の作成を開始します。 socketaddressアドレス= new inetsocketAddress(host、port); 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"; // request line //リクエストヘッダーを作成-HTTPリクエストヘッダー(リクエストヘッダー)文字列hostheader = "host:" + host + "/r/n"; string acceptheader = "accept: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. 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"); //ヘッダーメッセージをリクエストして、end flashwriter.flush()を送信します。
4. HTTP応答を受け入れ、コンテンツを解析し、作成したファイルに書き込みます
// HTTP応答ヘッダーを受け入れ、CustomDatainputStreamを解析する準備= new CustomDatainputStream(socket.getInputStream());ファイルmyfile = new file(fileinfo.getStorElocation() + file.separator + fileInfo.getFileName());文字列コンテンツ= null; httpresponseheaderparser responseheader = new httpresponseheaderparser(); BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(MyFile)); boolean hasdata = false; while((content = input.readhttppresponseheaderline()!= null){system.out.println( "response header contact- >>" + content); ResponseHeader.AddResponseHeaderline(content); if(content.length()== 0){hasdata = true; } if(hasdata){int totalbytes = responseheader.getFileLength(); if(totalbytes == 0)break; //応答なしボディとデータ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;壊す; }}シンプルなHTTP応答ヘッダー解析クラスHTTPRESPONSEHEADERPARSERコードは次のとおりです。
パッケージcom.gloomyfish.socket.tutorial.http.download; java.util.hashmapをインポートします。 java.util.mapをインポートします。 /** *エンティティヘッダー、応答ヘッド、および応答ライン<ステータスコード、charset、ect ...> * RFC2616を参照できます。 HTTP応答ヘッダーについては、詳細に説明されているRFCドキュメントをご覧ください! ! */ public class httpresponseheaderparser {public final static string content_length = "content-length"; public final static string content_type = "content-type"; public final static string accect_ranges = "accetp-ranges";プライベートマップ<文字列、文字列> headermap; public httpresponseheaderparser(){headermap = new hashmap <string、string>(); }/** * <p>応答ヘッダーキー値ペアを取得</p> * @param Responseheaderline */public void addResponseHeaderline(String ResponseHeaderline){if(ResponseHeadLine.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> getallheaders(){return headermap; }}上記はこの記事に関するものです。誰もがJavaプログラミングを学ぶことが役立つことを願っています。