HttpClient入门(一)

本文详细介绍了Apache HttpClient库的使用方法,包括其简介、功能特性及如何在Java应用中实现高效HTTP协议支持。文章指导读者安装并运用HttpClient进行GET和POST方法调用,同时讨论了自动转向、HTTPS协议支持、代理服务器等功能,以及如何处理异常和释放连接。通过实例演示,读者可以掌握HttpClient的基本功能和实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇文章转自http://www.ibm.com/developerworks/cn/opensource/os-httpclient/

发布日期为2005 年 11 月 10 日,学习用

1 HttpClient简介

    HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。

    HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient,更多使用 HttpClient 的应用可以参见http://wiki.apache.org/jakarta-httpclient/HttpClientPowered。HttpClient 项目非常活跃,使用的人还是非常多的。


2 HttpClient 功能介绍
    以下列出的是 HttpClient 提供的主要的功能,要知道更多详细的功能可以参见 HttpClient 的主页。
    (1)实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
    (2)支持自动转向
    (3)支持 HTTPS 协议

    (4)支持代理服务器等

   下面将逐一介绍怎样使用这些功能。首先,我们必须安装好 HttpClient。
   (1)HttpClient 可以在http://jakarta.apache.org/commons/httpclient/downloads.html下载
  (2)HttpClient 用到了 Apache Jakarta common 下的子项目 logging,你可以从这个地址http://jakarta.apache.org/site/downloads/downloads_commons-logging.cgi下载到 common logging,从下载后的压缩包中取出 commons-logging.jar 加到 CLASSPATH 中

 (3)HttpClient 用到了 Apache Jakarta common 下的子项目 codec,你可以从这个地址http://jakarta.apache.org/site/downloads/downloads_commons-codec.cgi 下载到最新的 common codec,从下载后的压缩包中取出 commons-codec-1.x.jar 加到 CLASSPATH 中


3 HttpClient 基本功能的使用
3.1 GET 方法

   使用 HttpClient 需要以下 6 个步骤:
   1. 创建 HttpClient 的实例

     大部分情况下 HttpClient 默认的构造函数已经足够使用。         

     HttpClient httpClient = new HttpClient();

    2. 创建某种连接方法的实例,在这里是 GetMethod。在 GetMethod 的构造函数中传入待连接的地址

     在GET方法的构造函数中传入待连接的地址即可。用GetMethod将会自动处理转发过程,如果想要把自动处理转发过程去掉的话,可以调用方法setFollowRedirects(false)。

    GetMethod getMethod = new GetMethod("http://www.ibm.com/");

   3. 调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 method 实例

    调用实例httpClient的executeMethod方法来执行getMethod。

   由于是执行在网络上的程序,在运行executeMethod方法的时候,需要处理两个异常,分别是HttpExceptionIOException引起第一种异常的原因主要可能是在构造getMethod的时候传入的协议不对,比如不小心将"http"写成"htp",或者服务器端返回的内容不正常等,并且该异常发生是不可恢复的;第二种异常一般是由于网络原因引起的异常,对于这种异常 (IOException),HttpClient会根据你指定的恢复策略自动试着重新执行executeMethod方法。HttpClient的恢复策略可以自定义(通过实现接口HttpMethodRetryHandler来实现)。通过httpClient的方法setParameter设置你实现的恢复策略,本文中使用的是系统提供的默认恢复策略,该策略在碰到第二类异常的时候将自动重试3次。

   executeMethod返回值是一个整数,表示了执行该方法后服务器返回的状态码,该状态码能表示出该方法执行是否成功、需要认证或者页面发生了跳转(默认状态下GetMethod的实例是自动处理跳转的)等。    

     //设置成了默认的恢复策略,在发生异常时候将自动重试3次,在这里你也可以设置成自定义的恢复策略
     getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler()); 
     //执行getMethod
     int statusCode = client.executeMethod(getMethod);
     if (statusCode != HttpStatus.SC_OK) {
            System.err.println("Method failed: " + getMethod.getStatusLine());
        }

   4. 读 response

   在返回的状态码正确后,即可取得内容。取得目标地址的内容有三种方法:

   第一种,getResponseBody,该方法返回的是目标的二进制的byte流;

   第二种,getResponseBodyAsString,这个方法返回的是String类型,值得注意的是该方法返回的String的编码是根据系统默认的编码方式,所以返回的String值可能编码类型有误,在本文的"字符编码"部分中将对此做详细介绍;

   第三种,getResponseBodyAsStream,这个方法对于目标地址中有大量数据需要传输是最佳的。

    byte[] responseBody = method.getResponseBody();   

   5. 释放连接。无论执行方法是否成功,都必须释放连接

    method.releaseConnection();
   6. 对得到后的内容进行处理

       处理内容。在这一步中根据你的需要处理内容,在例子中只是简单的将内容打印到控制台。
    
System.out.println(new String(responseBody));
    

    全部的代码:

package test;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
public class GetSample{
  public static void main(String[] args) {
  //构造HttpClient的实例
  HttpClient httpClient = new HttpClient();
  //创建GET方法的实例
  GetMethod getMethod = new GetMethod("http://www.ibm.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());
   }
   //读取内容 
   byte[] responseBody = getMethod.getResponseBody();
   //处理内容
   System.out.println(new String(responseBody));
  } catch (HttpException e) {
   //发生致命的异常,可能是协议不对或者返回的内容有问题
   System.out.println("Please check your provided http address!");
   e.printStackTrace();
  } catch (IOException e) {
   //发生网络异常
   e.printStackTrace();
  } finally {
   //释放连接
   getMethod.releaseConnection();
  }
 }
}

3.2 POST方法
    根据RFC2616,对POST的解释如下:POST方法用来向目的服务器发出请求,要求它接受被附在请求后的实体,并把它当作请求队列(Request-Line)中请求URI所指定资源的附加新子项。

   POST被设计成用统一的方法实现下列功能:
  (1)对现有资源的注释(Annotation of existing resources)
  (2)向电子公告栏、新闻组,邮件列表或类似讨论组发送消息
  (3)提交数据块,如将表单的结果提交给数据处理过程
  (4)通过附加操作来扩展数据库
   调用HttpClient中的PostMethod与GetMethod类似,除了设置PostMethod的实例与GetMethod有些不同之外,剩下的步骤都差不多。在下面的例子中,省去了与GetMethod相同的步骤,只说明与上面不同的地方,并以登录清华大学BBS为例子进行说明。
    构造PostMethod之前的步骤都相同,与GetMethod一样,构造PostMethod也需要一个URI参数,在本例中,登录的地址是http://www.newsmth.net/bbslogin2.php。在创建了PostMethod的实例之后,需要给method实例填充表单的值,在BBS的登录表单中需要有两个域,第一个是用户名(域名叫id),第二个是密码(域名叫passwd)。表单中的域用类NameValuePair来表示,该类的构造函数第一个参数是域名,第二参数是该域的值;将表单所有的值设置到PostMethod中用方法setRequestBody。另外由于BBS登录成功后会转向另外一个页面,但是HttpClient对于要求接受后继服务的请求,比如POST和PUT,不支持自动转发,因此需要自己对页面转向做处理。具体的页面转向处理请参见下面的"自动转向"部分。代码如下:

String url = "http://www.newsmth.net/bbslogin2.php";
PostMethod postMethod = new PostMethod(url);
// 填入各个表单域的值
NameValuePair[] data = { new NameValuePair("id", "youUserName"),new NameValuePair("passwd", "yourPwd") };
   // 将表单的值放入postMethod中
   postMethod.setRequestBody(data);
   // 执行postMethod
    int statusCode = httpClient.executeMethod(postMethod);
  // HttpClient对于要求接受后继服务的请求,象POST和PUT等不能自动处理转发
  // 301或者302
  if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY ||statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
    // 从头中取出转向的地址
    Header locationHeader = postMethod.getResponseHeader("location");
    String location = null;
    if (locationHeader != null) {
     location = locationHeader.getValue();
     System.out.println("The page was redirected to:" + location);
    } else {
     System.err.println("Location field value is null.");
    }
    return;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值