The Http client program has been integrated into the Java language and can be called through the URLConnection class. Unfortunately, SUN has not published the source code of the Http client program, and its implementation details are still a mystery. Based on the HTTP protocol specification, This article uses the Java.net. Socket class to implement an HTTP client program.
1. Socket class:
Readers who know about TCP/IP protocol set communication know that inter-protocol communication is completed through Socket. In the Java.net package, the Socket class is the specific implementation of the Socket. After connecting to the host, it returns an I/O Stream to exchange information between protocols.
2. HTTP protocol
The HTTP protocol, like other protocols in the TCP/IP protocol set, follows the customer/server model. The format of the information sent from the client to the server is as follows:
Request Method url http Protocol version
Submitted metadata
** Empty rows **
Entity
The request method is a description of this connection. Currently, the HTTP protocol has been developed to Version 1.1, which includes seven types: GET, HEAD, POST, DELETE, OPTIONS, TRACE, and PUT. Metadata is information about the current request. By analyzing the metadata, you can check whether the object data is complete, whether the receiving process is incorrect, and whether the type is matched. The introduction of metadata makes HTTP Communication more secure and reliable. The entity is the specific content of the request.
Send the preceding message to the Web server. If the message is sent successfully, the response format is as follows:
HTTP Protocol version number response status code Description
Received meta information
** Empty rows **
Entity
The preceding message is sent to the client and received successfully. The connection is closed and a handshake is completed. The following describes the specific packet application using the most common GET method:
GET http://www.youhost.com HTTP/1.0
Accept: www/source; text/html; image/gif; image/jpeg ;*/*
User_Agent: myAgent
** Empty rows **
This message requests a default HTML document from the host www.youhost.com. The HTTP Protocol version of the client is 1.0. the meta information includes the format of the file that can be received. The user agent separates each segment with a line break and ends with a blank line. After sending to the server, if the execution process is normal, the server returns the following code:
HTTP/1.1 200 OK
Date: Tue, 14 Sep 1999 02:19:57 GMT
Server: Apache/1.2.6
Connection: close
Content-Type: text/html
** Empty rows **
<Html>
HTTP/1.1 indicates that the HTTP server is Version 1.1, 200 indicates the server's response status code to the customer's request, and OK indicates the explanation of the response status code, the metadata and body of this document are followed. (For details about the response status code and metadata, see the draft Inetrnet standard: RFC2616 ).
3. HTTP client program:
Import java.net .*;
Import java. io .*;
Import java. util. Properties;
Import java. util. Enumeration;
Public class Http {
Protected Socket client;
Protected BufferedOutputStream sender;
Protected BufferedInputStream aggreger;
Protected ByteArrayInputStream byteStream;
Protected URL target;
Private int responseCode =-1;
Private String responseMessage = "";
Private String serverVersion = "";
Private Properties header = new Properties ();
Public Http (){}
Public Http (String url ){
GET (url );
}
/* Based on the URL, the GET method will request files, database query results, program running results, and other content */
Public void GET (String url ){
Try {
CheckHTTP (url );
OpenServer (target. getHost (), target. getPort ());
String cmd = "GET" + getURLFormat (target) + "HTTP/1.0"
+ GetBaseHeads () + "";
SendMessage (cmd );
ReceiveMessage ();
} Catch (ProtocolException p ){
P. printStackTrace ();
Return;
} Catch (UnknownHostException e ){
E. printStackTrace ();
Return;
} Catch (IOException I)
I. printStackTrace ();
Return;
}
}
/*
* The HEAD method only requests URL meta information, excluding the URL itself. If you suspect that
* If the files are the same, use this method to check whether the files are quick and effective.
*/
Public void HEAD (String url ){
Try {
CheckHTTP (url );
OpenServer (target. getHost (), target. getPort ());
String cmd = "HEAD" + getURLFormat (target) + "HTTP/1.0"
+ GetBaseHeads () + "";
SendMessage (cmd );
ReceiveMessage ();
} Catch (ProtocolException p ){
P. printStackTrace ();
Return;
} Catch (UnknownHostException e ){
E. printStackTrace ();
Return;
} Catch (IOException I)
I. printStackTrace ();
Return;
}
}
/*
* The POST method transmits data to the server for processing. For example
* Submit a table.
*/
Public void POST (String url, String content ){
Try {
CheckHTTP (url );
OpenServer (target. getHost (), target. getPort ());
String cmd = "POST" + getURLFormat (target) +"
HTTP/1.0 "+ getBaseHeads ();
Cmd + = "Content-type: application/x-www-form-urlencoded ";
Cmd + = "Content-length:" + content. length () + "";
Cmd + = content + "";
SendMessage (cmd );
ReceiveMessage ();
} Catch (ProtocolException p ){
P. printStackTrace ();
Return;
} Catch (UnknownHostException e ){
E. printStackTrace ();
Return;
} Catch (IOException I)
I. printStackTrace ();
Return;
}
}
Protected void checkHTTP (String url) throws ProtocolException {
Try {
URL target = new URL (url );
If (target = null |! Target. getProtocol (). toUpperCase (). equals ("HTTP "))
Throw new ProtocolException ("this is not an HTTP Protocol ");
This.tar get = target;
} Catch (MalformedURLException m ){
Throw new ProtocolException ("protocol format error ");
}
}
/*
* Connect to the Web server. If the Web server cannot be found, InetAddress will cause UnknownHostException.
* Exception. If the Socket connection fails, an IOException is thrown.
*/
Protected void openServer (String host, int port) throws
UnknownHostException, IOException {
Header. clear ();
ResponseMessage = ""; responseCode =-1;
Try {
If (client! = Null) closeServer ();
If (byteStream! = Null ){
ByteStream. close (); byteStream = null;
}
InetAddress address = InetAddress. getByName (host );
Client = new Socket (address, port =-1? 80: port );
Sender = new BufferedOutputStream (client. getOutputStream ());
Extends ER = new BufferedInputStream (client. getInputStream ());
} Catch (UnknownHostException u ){
Throw u;
} Catch (IOException I ){
Throw I;
}
}
/* Close the connection to the Web server */
Protected void closeServer () throws IOException {
If (client = null) return;
Try {
Client. close (); sender. close (); cycler. close ();
} Catch (IOException I ){
Throw I;
}
Client = null; sender = null; Consumer ER = null;
}
Protected String getURLFormat (URL target ){
String spec = "http: //" + target. getHost ();
If (target. getPort ()! =-1)
Spec + = ":" + target. getPort ();
Return spec + = target. getFile ();
}
/* Transfer data to the Web server */
Protected void sendMessage (String data) throws IOException {
Sender. write (data. getBytes (), 0, data. length ());
Sender. flush ();
}
/* Receive data from the Web server */
Protected void receiveMessage () throws IOException {
Byte data [] = new byte [1024];
Int count = 0;
Int word =-1;
// Parse the first line
While (word = author er. read ())! =-1 ){
If (word = | word = ){
Word = author er. read ();
If (word =) word = author er. read ();
Break;
}
If (count = data. length) data = addCapacity (data );
Data [count ++] = (byte) word;
}
String message = new String (data, 0, count );
Int mark = message. indexOf (32 );
ServerVersion = message. substring (0, mark );
While (mark
ResponseCode = Integer. parseInt (message. substring (mark + 1, mark + = 4 ));
ResponseMessage = message. substring (mark, message. length (). trim ();
// You can add the response status code and process it.
Switch (responseCode ){
Case 400:
Throw new IOException ("error request ");
Case 404:
Throw new FileNotFoundException (getURLFormat (target ));
Case 503:
Throw new IOException ("server unavailable ");
}
If (word =-1) throw new ProtocolException ("message receiving exception termination ");
Int symbol =-1;
Count = 0;
// Parse metadata
While (word! = & Word! = & Word>-1 ){
If (word =) word = 32;
If (count = data. length) data = addCapacity (data );
Data [count ++] = (byte) word;
ParseLine :{
While ((