HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient简介 HTTP 协议可能是现在 Internet上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。所以HttpClient很好的弥补了JDK 在这一个方面的缺憾。
需要jar包的地址:
commons-httpclient-3.1-rc1.jar: http://jakarta.apache.org/commons/httpclient/downloads.html
commons-logging-1.1.jar: http://jakarta.apache.org/site/downloads/downloads_commons-logging.cgi
commons-codec-1.3.jar: http://jakarta.apache.org/site/downloads/downloads_commons-codec
既然是访问服务器,其实主要就是get与post的过程。在访问网页的时候我们知道,一般的访问就是直接地点击链接得到网页或是通过提交一些数据才能访问到所需的网页。简单的说,那么前者就是一个get的过程,后者就是post的过程。
一般一个get的过程需要以下几步:
1. 创建 HttpClient 的实例
2. 创建某种连接方法的实例,在这里是 GetMethod。在 GetMethod 的构造函数中传入待连接的地址
3. 调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 GetMethod 实例
4. 释放连接。无论执行方法是否成功,都必须释放连接
5. 对得到后的内容进行处理
注意在第五步的时候存在着三种取得目标内容的方法:
1. getResponseBody,该方法返回的是目标的二进制的byte流;
2. getResponseBodyAsString,这个方法返回的是String类型;
3. getResponseBodyAsStream,这个方法对于目标地址中有大量数据需要传输;
具体情况根据实际情况而定.
附*问网易首页的的代码:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
public class GetSample {
/**采用数据流的方式读取页面数据,最后以字符串的形式呈现。
* get
*/
public static void main(String[] args) {
//构造HttpClient的实例
HttpClient httpClient = new HttpClient();
//创建GET方法的实例
GetMethod getMethod = new GetMethod("http://www.163.com");
//使用系统提供的默认的恢复策略
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler());
try {
//执行getMethod
int statusCode = httpClient.executeMethod(getMethod);
if (statusCode != HttpStatus.SC_OK)
{
System.err.println("Method failed: "+ getMethod.getStatusLine());
}
//采用流的方式来处理数据,此方法适用于大量的数据。
InputStream in = getMethod.getResponseBodyAsStream();
byte[] responseBody = null;
if (in!=null)
{
byte[] tmp = new byte[4096];
int bytesRead = 0;
ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
while((bytesRead = in.read(tmp))!=-1)
{
buffer.write(tmp,0,bytesRead);
}
responseBody = buffer.toByteArray();
}
System.out.println(new String(responseBody));
System.out.println(httpClient.getPort());
//System.out.println(responseBody.);
}
catch (HttpException e)
{
//发生致命的异常,可能是协议不对或者返回的内容有问题
System.out.println("Please check your provided http address!");
e.printStackTrace();
}
catch (IOException e)
{
//发生网络异常
e.printStackTrace();
}
finally
{
//释放连接
getMethod.releaseConnection();
}
}
}
同样,post的过程如下:
1. 创建 HttpClient 的实例
2. 创建某种连接方法的实例,在这里是 PostMethod。在 PostMethod 的构造函数中传入待连接的地址
3. 需要对2步创建的实例设置表单值(比如用户名或密码)
4. 调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 PostMethod 实例
5. 释放连接。无论执行方法是否成功,都必须释放连接
6. 对得到后的内容进行处理
附上的登陆163的代码:
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.cookie.CookieSpec;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
public class PostSample {
/**
* post方法中带用户名和密码的登陆,没有页面定向,适用于163
*
*/
static final String LOGON_SITE = "reg.163.com";
static final int LOGON_PORT = 80;
public static void main(String[] args) throws Exception{
HttpClient client = new HttpClient();
client.getHostConfiguration().setHost(LOGON_SITE,LOGON_PORT);
PostMethod post = new PostMethod("/logins.jsp");
//设置登陆需要的几个参数
NameValuePair name = new NameValuePair("username","********");
NameValuePair pass = new NameValuePair("password","********");
post.setRequestBody(new NameValuePair[]{name,pass});
//因为logins.jsp中并没有涉及到页面重定向,所以location中并没有数据。
int status = client.executeMethod(post);
System.out.println(post.getResponseBodyAsString());
post.releaseConnection();
}
}