타사 라이브러리가 없으면 최소한의 HTTP 파일 다운로드 클라이언트가 Java 소켓을 기반으로 구현됩니다. 소켓을 통해 소켓을 통해 파일을 다운로드하기위한 HTTP 요청 헤더를 구현하는 방법에 대한 완전한 시연을 통해 소켓에서 HTTP 응답 (응답 헤더, 응답 본문) 패킷을 보내고 파일 내용을 저장합니다. 스윙 워크를 통해 UI 새로 고침을 실현하여 실시간으로 다운로드 진행 상황을 표시하는 방법.
먼저 UI 부분을보십시오.
【다운로드 추가】 버튼 :
팝업 URL 입력 상자를 클릭하십시오. 사용자가 파일 URL을 입력 상자에 다운로드하려면 [확인] 버튼을 클릭하여 시작하십시오.
다운로드
【완전한 버튼 :
다운로드 된 모든 파일 목록을 지우십시오
파일 다운로드 상태는 다음 유형으로 나뉩니다.
패키지 com.gloomyfish.socket.tutorial.http.download; public enum downloadstatus {not_started, in_process, 완료, 오류}} UI 부품은 주로 스윙 구성 요소를 사용하여 수행됩니다. [다운로드 추가]를 클릭하여 다음과 같이 코드를 실행하십시오.
최종 jdialog 대화 상자 = new JDialog (이것은 "파일 링크 추가", true); dialog.getContentPane (). setLayout (new BorderLayout ()); // dialog.setsize (new Dimension (400,200)); 최종 UrlFilePanel 패널 = New UrlFilePanel (); PALEN.SETUPLISTERE (new ActionListener () {@override public void actionPerformed (actionEvent e) {if ( "ok".Equals (e.getActionCommand ()))) {if (panel.validateInput ()) {downloadDetailStatusInfomodel Data = new DownloadDetailStatusInfomodel (panel.getValidFileUlUll); tablemodel.getdata ()는 startdownlaod (); dialog.getContentPane (). add (PANEL, BORTHLAYOUT.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 (창 w) {dimension us = w.getsize (); dimension them = toolkit.getDefaultToolKit (). getScreensize (); int newx = (그들 .width -us.width) / 2; int newy = (그들. 하이 사이트 - 미국. 하이이트) / 2; W. 세트로 위치 (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 status-codesp rase-phrase crlf, 상태 줄의 간단한 예는 다음과 같습니다. 상태-라인 = http/1.1 200 Ok 일반적으로, 모든 사람이 좋아하는 모든 프롬프트는 많은 프롬프트를 제공하는 상태 코드입니다. 가장 일반적인 것은 404, 500 등의 상태 코드입니다. 파일을 다운로드하는 가장 중요한 것은 HTTP 응답 헤더에서 컨텐츠 길이 및 컨텐츠 유형을 확인하는 것입니다.
파일의 길이와 유형은 별도로 선언됩니다. 수락 범위와 같은 다른 것들은 얼마나 많은 바이트가 수용되는지를 나타냅니다. 멀티 스레드 다운로드에 사용할 수 있습니다. HTTP 요청 및 응답의 패킷 형식을 이해 한 후 소켓을 통해 패킷 형식으로 컨텐츠를 구문 분석하고 HTTP 요청 및 응답을 보내고 읽을 수 있습니다. 특정 단계
다음과 같이 :
1. 사용자가 입력 한 URL 파일을 기반으로 소켓 연결을 설정합니다.
url url = new URL (fileInfo.getFileUrl ()); 문자열 호스트 = url.gethost (); int port = (url.getport () == -1)? url.getDefaultport () : url.getport (); System.out.println ( "호스트 이름 =" + host); System.out.println ( "port =" + port); System.out.println ( "file uri =" + url.getfile ()); // 소켓을 만들고 요청 라인 소켓 소켓을 구성하기 시작합니다. 소켓 소켓 = 새로운 소켓 (); SocketAddress address = new inetSocketAddress (호스트, 포트); socket.connect (주소);
URL 클래스는 사용자가 입력 한 URL 문자열을 구문 분석하기 쉬운 URL로 전환하는 데 사용됩니다.
2. HTTP 요청을 구성하십시오
BufferedWriter BufferedWriter = New BufferedWriter (New OutputStreamWriter (socket.getoutPutStream (), "UTF8")); 문자열 requeststr = "get" + url.getFile () + "http/1.1/r/n"; // 요청 행을 요청하십시오. String AccepTheader = "accept : text/html, application/xhtml+xml, application/xml; q = 0.9,*/*; q = 0.8/r/n"; 문자열 charsetheader = "accept-charset : gbk, utf-8; q = 0.7,*; q = 0.3/r/n"; String Lang String keepheader = "연결 : 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 응답 및 컨텐츠를 구문 분석하고 생성 된 파일에 쓰기
// HTTP 응답 헤더 및 구문 분석 준비 준비 CustomDatainputStream input = 새로운 CustomDatainputStream (socket.getInputStream ()); file myFile = 새 파일 (fileInfo.getStorElocation () + file.separator + fileInfo.getFilename ()); 문자열 내용 = null; httpresponseheaderparser responseheader = new httpresponseheaderparser (); BufferedOutputStream output = new BufferedOutputStream (new FileOutputStream (MyFile)); 부울 hasdata = false; while ((content = input.readhttpresponseheaderline ())! = null) {system.out.println ( "응답 헤더 연락 ->>" + content); ResponseHeader.AddResponseHeaderLine (컨텐츠); if (content.length () == 0) {hasdata = true; } if (hasdata) {int totalbytes = responseHeader.getFilElength (); if (TotalBytes == 0) 브레이크; // 응답 본문과 데이터가 없음 int 오프셋 = 0; 바이트 [] myData = null; if (TotalBytes> = 2048) {mydata = new Byte [2048]; } else {myData = 새로운 바이트 [TotalBytes]; } int numofbytes = 0; while ((numofbytes = input.read (myData, 0, myData.length))> 0 && 오프셋 <TotalBytes) {offset += numofbytes; float p = ((float) 오프셋) / ((float) TotalBytes) * 100.0f; if (offset> totalBytes) {numofbytes = numofbytes + totalBytes- 오프셋; p = 100.0f; } output.write (myData, 0, numofbytes); Updatestatus (P); } hasdata = false; 부서지다; }} 간단한 HTTP 응답 헤더 구문 분석 클래스 HTTPRESPONSEHEADERPARSER 코드는 다음과 같습니다.
패키지 com.gloomyfish.socket.tutorial.http.download; java.util.hashmap import; java.util.map import; /** * 엔티티 헤더, 응답 헤드 * 및 응답 라인 <상태 코드, charset, ect ...> *를 구문 분석 할 수 있습니다. HTTP 응답 헤더는 RFC 문서를 참조하십시오.이 문서는 자세히 설명되어 있습니다! ! */ public class httpresponseheaderparser {public final static string content_length = "Content-Length"; 공개 최종 정적 문자열 content_type = "Content-Type"; 공개 최종 정적 문자열 accept_ranges = "accetp-ranges"; 비공개 맵 <문자열, 문자열> 헤일 맵; public httpresponseHeadERPARSER () {readermap = new Hashmap <String, String> (); }/** * <p> 응답 헤더 키 값 쌍 쌍 </p> * @param responseHeaderLine */public void addResponseHeaderLine (String responseHeaderLine) {if (responseHeaderLine.contains ( ":")) {keyValue = responsheaderline.split ( ":"); if (keyValue [0] .EqualSeignoreCase (content_length)) {readermap.put (content_length, keyValue [1]); } else if (keyValue [0] .EqualSeignoreCase (content_type)) {readermap.put (content_type, keyValue [1]); } else {readermap.put (keyValue [0], keyValue [1]); }}} public int getfilelength () {if (remermap.get (content_length) == null) {return 0; } return integer.parseint (rebidermap.get (content_length)); } public String getFileType () {return rebordmap.get (content_type); } public map <string, String> getAllHeaders () {return rebordmap; }}위의 내용은이 기사에 관한 모든 것입니다. 모든 사람들이 Java 프로그래밍을 배우는 것이 도움이되기를 바랍니다.