Http客户端程序已集成在Java语言中可以通过URLConnection类调用遗憾的
是由于SUN没有公布Http客户程序的源码它实现的细节仍是一个谜本文根据HTTP
协议规范用Socket类实现一个HTTP协议客户端程序
Socket类:
了解TCP/IP协议集通信的读者知道协议间的通信是通过Socket完成的在
包中Socket类就是对Socket的具体实现它通过连接到主机后返回一个
I/O流实现协议间的信息交换
HTTP协议
HTTP协议同其它TCP/IP协议集中的协议一样是遵循客户/服务器模型工作的客
户端发往服务端的信息格式如下:
请求方法 URL HTTP协议的版本号
提交的元信息
**空行**
实体
请求方法是对这次连接工作的说明目前HTTP协议已经发展到版它包括GET
HEADPOSTDELETEOPTIONSTRACEPUT七种元信息是关于当前请求的信息通
过分析元信息可以检查实体数据是否完整接收过程是否出错类型是否匹配等元
信息的引入使HTTP协议通信更加稳妥可靠实体是请求的具体内容
将上述报文发往Web服务器如果成功应答格式如下:
HTTP协议的版本号 应答状态码 应答状态码说明
接收的元信息
**空行**
实体
以上报文发向客户端并且接收成功彼此间关闭连接完成一次握手
下面用最常用的GET方法来说明具体的报文应用
GET HTTP/
accept: www/source; text/html; image/gif; image/jpeg; */*
User_Agent: myAgent
**空行**
这个报文是向主机请求一个缺省HTML文档客户端HTTP协议版本
号是版元信息包括可接收的文件格式用户代理每一段之间用回车换行符分
隔最后以一个空行结束发向服务器后如果执行过程正常服务器返回以下代码:
HTTP/ OK
Date: Tue Sep :: GMT
Server: Apache/
Connection: close
ContentType: text/html
**空行**
HTTP/表示这个HTTP服务器是版是服务器对客户请求的应答状态码OK
是对应答状态码的解释之后是这个文档的元信息和文档正文(相关应答状态码和元
信息的解释请参阅Inetrnet标准草案:RFC)
HTTP客户端程序:
import *;
import javaio*;
import javautilProperties;
import javautilEnumeration;
public class Http {
protected Socket client;
protected BufferedOutputStream sender;
protected BufferedInputStream receiver;
protected ByteArrayInputStream byteStream;
protected URL target;
private int responseCode=;
private String responseMessage=;
private String serverVersion=;
private Properties header = new Properties();
public Http() { }
public Http(String url) {
GET(url) ;
}
/* GET方法根据URL会请求文件数据库查询结果程序运行结果等多种内容 */
public void GET(String url) {
try {
checkHTTP(url);
openServer(targetgetHost()targetgetPort() );
String cmd = GET + getURLFormat(target) + HTTP/\r\n
+ getBaseHeads()+\r\n;
sendMessage(cmd);
receiveMessage();
}catch(ProtocolException p) {
pprintStackTrace();
return;
}catch(UnknownHostException e) {
eprintStackTrace();
return;
}catch(IOException i)
iprintStackTrace();
return;
}
}
/*
* HEAD方法只请求URL的元信息不包括URL本身若怀疑本机和服务器上的
* 文件相同用这个方法检查最快捷有效
*/
public void HEAD(String url) {
try {
checkHTTP(url);
openServer(targetgetHost()targetgetPort() );
String cmd = HEAD +getURLFormat(target)+ HTTP/\r\n
+getBaseHeads()+\r\n;
sendMessage(cmd);
receiveMessage();
}catch(ProtocolException p) {
pprintStackTrace();
return;
}catch(UnknownHostException e) {
eprintStackTrace();
return;
}catch(IOException i)
iprintStackTrace();
return;
}
}
/*
* POST方法是向服务器传送数据以便服务器做出相应的处理例如网页上常用的
* 提交表格
*/
public void POST(String urlString content) {
try {
checkHTTP(url);
openServer(targetgetHost()targetgetPort() );
String cmd = POST + getURLFormat(target) +
HTTP/\r\n+getBaseHeads();
cmd += Contenttype: application/xwwwformurlencoded\r\n;
cmd += Contentlength: + contentlength() + \r\n\r\n;
cmd += content+\r\n;
sendMessage(cmd);
receiveMessage();
}catch(ProtocolException p) {
pprintStackTrace();
return;
}catch(UnknownHostException e) {
eprintStackTrace();
return;
}catch(IOException i)
iprintStackTrace();
return;
}
}
protected void checkHTTP(String url) throws ProtocolException {
try {
URL target = new URL(url);
if(target==null || !targetgetProtocol()toUpperCase()equals(HTTP) )
throw new ProtocolException(这不是HTTP协议);
thistarget = target;
}catch(MalformedURLException m) {
throw new ProtocolException(协议格式错误);
}
}
/*
* 与Web服务器连接若找不到Web服务器InetAddress会引发UnknownHostException
* 异常若Socket连接失败会引发IOException异常
*/
protected void openServer(String hostint port) throws
UnknownHostExceptionIOException {
headerclear();
responseMessage=; responseCode=;
try {
if(client!=null) closeServer();
if(byteStream != null) {
byteStreamclose(); byteStream=null;
}
InetAddress address = InetAddressgetByName(host);
client = new Socket(addressport==?:port);
sender = new BufferedOutputStream(clientgetOutputStream());
receiver = new BufferedInputStream(clientgetInputStream());
}catch(UnknownHostException u) {
throw u;
}catch(IOException i) {
throw i;
}
}
/* 关闭与Web服务器的连接 */
protected void closeServer() throws IOException {
if(client==null) return;
try {
clientclose(); senderclose(); receiverclose();
}catch(IOException i) {
throw i;
}
client=null; sender=null; receiver=null;
}
protected String getURLFormat(URL target) {
String spec = //+targetgetHost();
if(targetgetPort()!=)
spec+=:+targetgetPort();
return spec+=targetgetFile();
}
/* 向Web服务器传送数据 */
protected void sendMessage(String data) throws IOException{
senderwrite(datagetBytes()datalength());
senderflush();
}
/* 接收来自Web服务器的数据 */
protected void receiveMessage() throws IOException{
byte data[] = new byte[];
int count=;
int word=;
// 解析第一行
while( (word=receiverread())!= ) {
if(word==\r||word==\n) {
word=receiverread();
if(word==\n) word=receiverread();
break;
}
if(count == datalength) data = addCapacity(data);
data[count++]=(byte)word;
}
String message = new String(datacount);
int mark = messageindexOf();
serverVersion = messagesubstring(mark);
while( markresponseCode = Integer.parseInt(message.substring(mark+1,mark+=4));responseMessage = message.substring(mark,message.length()).trim();