专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »编程综合 » httpclient:HttpClient入门 »正文

httpclient:HttpClient入门

来源: 发布时间:星期四, 2009年1月15日 浏览:9次 评论:0
  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/HttpClientPoweredHttpClient 项目非常活跃使用人还是非常多目前 HttpClient 版本是在 2005.10.11 发布 3.0 RC4

  HttpClient 功能介绍

  以下列出是 HttpClient 提供主要功能要知道更多详细功能可以参见 HttpClient 主页

  实现了所有 HTTP 思路方法(GET,POST,PUT,HEAD 等)

  支持自动转向

  支持 HTTPS 协议

  支持代理服务器等

  下面将逐介绍怎样使用这些功能首先我们必须安装好 HttpClient

  HttpClient 可以在http://jakarta.apache.org/commons/httpclient/downloads.html下载

  HttpClient 用到了 Apache Jakarta common 下子项目 logging你可以从这个地址http://jakarta.apache.org/site/downloads/downloads_commons-logging.cgi下载到 common logging从下载后压缩包中取出 commons-logging.jar 加到 CLASSPATH 中

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

  HttpClient 基本功能使用

  GET 思路方法

  使用 HttpClient 需要以下 6 个步骤:

  1. 创建 HttpClient 例子

  2. 创建某种连接思路方法例子在这里是 GetMethod在 GetMethod 构造中传入待连接地址

  3. 步中创建好例子 execute 思路方法来执行第 2步中创建好 method 例子

  4. 读 response

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

  6. 对得到后内容进行处理

  根据以上步骤我们来编写用GET思路方法来取得某网页内容代码

  大部分情况下 HttpClient 默认构造已经足够使用HttpClient httpClient = HttpClient;

  创建GET思路方法例子在GET思路方法构造中传入待连接地址即可用GetMethod将会自动处理转发过程如果想要把自动处理转发过程去掉可以思路方法FollowRedirects(false)GetMethod getMethod = GetMethod("http://www.ibm.com/");

  例子httpClientexecuteMethod思路方法来执行getMethod由于是执行在网络上在运行executeMethod思路方法时候需要处理两个异常分别是HttpException和IOException引起第种异常原因主要可能是在构造getMethod时候传入协议不对比如不小心将"http"写成"htp"或者服务器端返回内容不正常等并且该异常发生是不可恢复;第 2种异常般是由于网络原因引起异常对于这种异常 (IOException)HttpClient会根据你指定恢复策略自动试着重新执行executeMethod思路方法HttpClient恢复策略可以自定义(通过实现接口HttpMethodRetryHandler来实现)通过httpClient思路方法Parameter设置你实现恢复策略本文中使用是系统提供默认恢复策略该策略在碰到第 2类异常时候将自动重试3次executeMethod返回值是个整数表示了执行该思路方法后服务器返回状态码该状态码能表示出该思路方法执行是否成功、需要认证或者页面发生了跳转(默认状态下GetMethod例子是自动处理跳转)等//设置成了默认恢复策略在发生异常时候将自动重试3次在这里你也可以设置成自定义恢复策略
getMethod.getParams.Parameter(HttpMethodParams.RETRY_HANDLER,
       DefaultHttpMethodRetryHandler);
//执行getMethod
statusCode = client.executeMethod(getMethod);
(statusCode != HttpStatus.SC_OK) {
 .err.prln("Method failed: " + getMethod.getStatusLine);
}


  在返回状态码正确后即可取得内容取得目标地址内容有 3种思路方法:第getResponseBody该思路方法返回是目标 2进制流;第 2种getResponseBodyAsString这个思路方法返回是String类型值得注意是该思路方法返回String编码是根据系统默认编码方式所以返回String值可能编码类型有误在本文"编码"部分中将对此做详细介绍;第 3种getResponseBodyAsStream这个思路方法对于目标地址中有大量数据需要传输是最佳在这里我们使用了最简单getResponseBody思路方法 responseBody = method.getResponseBody;

  释放连接无论执行思路方法是否成功都必须释放连接method.releaseConnection;

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

  下面是完整代码这些代码也可在附件中test.GetSample中找到

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 GetSample{
 public void (String args) {
 //构造HttpClient例子
 HttpClient httpClient = HttpClient;
 //创建GET思路方法例子
 GetMethod getMethod = GetMethod("http://www.ibm.com");
 //使用系统提供默认恢复策略
 getMethod.getParams.Parameter(HttpMethodParams.RETRY_HANDLER,
   DefaultHttpMethodRetryHandler);
 try {
  //执行getMethod
  statusCode = httpClient.executeMethod(getMethod);
  (statusCode != HttpStatus.SC_OK) {
  .err.prln("Method failed: "
   + getMethod.getStatusLine);
  }
  //读取内容
  responseBody = getMethod.getResponseBody;
  //处理内容
  .out.prln( String(responseBody));
 } catch (HttpException e) {
  //发生致命异常可能是协议不对或者返回内容有问题
  .out.prln("Please check your provided http address!");
  e.prStackTrace;
 } catch (IOException e) {
  //发生网络异常
  e.prStackTrace;
 } finally {
  //释放连接
  getMethod.releaseConnection;
 }
}
}


  POST思路方法

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

  对现有资源注释(Annotation of existing resources)

  向电子公告栏、新闻组邮件列表或类似讨论组发送消息

  提交数据块如将表单结果提交给数据处理过程

  通过附加操作来扩展数据库

  HttpClient中PostMethod和GetMethod类似除了设置PostMethod例子和GetMethod有些区别的外剩下步骤都差不多在下面例子中省去了和GetMethod相同步骤只介绍说明和上面区别地方并以登录清华大学BBS为例子进行介绍说明

  构造PostMethod的前步骤都相同和GetMethod构造PostMethod也需要个URI参数在本例中登录地址是http://www.smth.net/bbslogin2.php在创建了PostMethod例子的后需要给method例子填充表单在BBS登录表单中需要有两个域个是用户名(域名叫id)第 2个是密码(域名叫passwd)表单中域用类NameValuePair来表示该类构造个参数是域名第 2参数是该域值;将表单所有值设置到PostMethod中用思路方法RequestBody另外由于BBS登录成功后会转向另外个页面但是HttpClient对于要求接受后继服务请求比如POST和PUT不支持自动转发因此需要自己对页面转向做处理具体页面转向处理请参见下面"自动转向"部分代码如下:String url = "http://www.smth.net/bbslogin2.php";
PostMethod postMethod = PostMethod(url);
// 填入各个表单域
NameValuePair data = { NameValuePair("id", "youUserName"),        
NameValuePair("passwd", "yourPwd") };
// 将表单值放入postMethod中
postMethod.RequestBody(data);
// 执行postMethod
statusCode = httpClient.executeMethod(postMethod);
// HttpClient对于要求接受后继服务请求象POST和PUT等不能自动处理转发
// 301或者302
(statusCode HttpStatus.SC_MOVED_PERMANENTLY ||
statusCode HttpStatus.SC_MOVED_TEMPORARILY) {
  // 从头中取出转向地址
  Header locationHeader = postMethod.getResponseHeader("location");
  String location = null;
   (locationHeader != null) {
   location = locationHeader.getValue;
   .out.prln("The page was redirected to:" + location);
  } {
   .err.prln("Location field value is null.");
  }
  ;
}


  完整代码请参见附件中test.PostSample

  使用HttpClient过程中常见些问题

  下面介绍在使用HttpClient过程中常见些问题

  编码

  某目标页编码可能出现在两个地方个地方是服务器返回http头中另外个地方是得到html/xml页面中

  在http头Content-Type字段可能会包含编码信息例如可能返回头会包含这样子信息:Content-Type: text/html; char=UTF-8这个头信息表明该页编码是UTF-8但是服务器返回头信息未必和内容能匹配上比如对于些双字节语言国家可能服务器返回编码类型是UTF-8但真正内容却不是UTF-8编码因此需要在另外地方去得到页面编码信息;但是如果服务器返回编码不是UTF-8而是具体些编码比如gb2312等那服务器返回可能是正确编码信息通过method对象getResponseCharSet思路方法就可以得到http头中编码信息

  对于象xml或者html这样文件允许作者在页面中直接指定编码类型比如在html中会有<meta http-equiv="Content-Type" content="text/html; char=gb2312"/>这样标签;或者在xml中会有<?xml version="1.0" encoding="gb2312"?>这样标签在这些情况下可能和http头中返回编码信息冲突需要用户自己判断到底那种编码类型应该是真正编码

  自动转向

  根据RFC2616中对自动转向定义主要有两种:301和302301表示永久移走(Moved Permanently)当返回是301则表示请求资源已经被移到个固定新地方任何向该地址发起请求都会被转到新地址上302表示暂时转向比如在服务器端servlet了sendRedirect思路方法则在客户端就会得到个302代码这时服务器返回头信息中location值就是sendRedirect转向目标地址

  HttpClient支持自动转向处理但是象POST和PUT方式这种要求接受后继服务请求方式暂时不支持自动转向因此如果碰到POST方式提交后返回是301或者302话需要自己处理就像刚才在POSTMethod中举例子:如果想进入登录BBS后页面必须重新发起登录请求请求地址可以在头字段location中得到不过需要注意有时候location返回可能是相对路径因此需要对location返回值做些处理才可以发起向新地址请求

  另外除了在头中包含信息可能使页面发生重定向外在页面中也有可能会发生页面重定向引起页面自动转发标签是:<meta http-equiv="refresh" content="5; url=http://www.ibm.com/us">如果你想在中也处理这种情况话得自己分析页面来实现转向需要注意在上面那个标签中url值也可以是个相对地址如果是这样需要对它做些处理后才可以转发

  处理HTTPS协议

  HttpClient提供了对SSL支持在使用SSL的前必须安装JSSE在Sun提供1.4以后版本中JSSE已经集成到JDK中如果你使用是JDK1.4以前版本则必须安装JSSEJSSE区别厂家有区别实现下面介绍如何使用HttpClient来打开Https连接这里有两种思路方法可以打开https连接种就是得到服务器颁发证书然后导入到本地keystore中;另外种办法就是通过扩展HttpClient类来实现自动接受证书

  思路方法1取得证书并导入本地keystore:

  安装JSSE (如果你使用JDK版本是1.4或者1.4以上就可以跳过这步)本文以IBMJSSE为例子介绍说明先到IBM网站WebSite上下载JSSE安装包然后解压开的后将ibmjsse.jar包拷贝到<java-home>libext目录下

  取得并且导入证书证书可以通过IE来获得:   1. 用IE打开需要连接https网址会弹出如下对话框:

Protocol("https", MySecureProtocolSocketFactory , 443);

  注册刚才创建https协议对象Protocol.registerProtocol("https ", myhttps);

  然后按照普通编程方式打开https目标地址代码请参见test.NoCerticationHttpsGetSample

  处理代理服务器

  HttpClient中使用代理服务器非常简单HttpClient中Proxy思路方法就可以思路方法个参数是代理服务器地址第 2个参数是端口号另外HttpClient也支持SOCKS代理

httpClient.getHostConfiguration.Proxy(hostName,port);

  结论

  从上面介绍中可以知道HttpClient对http协议支持非常好使用起来很简单版本更新快功能也很强大具有足够灵活性和扩展性对于想在Java应用中直接访问http资源编程人员来说HttpClient是个不可多得好工具

0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: