HttpClient及有关jar包详解_第1页
HttpClient及有关jar包详解_第2页
HttpClient及有关jar包详解_第3页
HttpClient及有关jar包详解_第4页
HttpClient及有关jar包详解_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实用文案HttpClient 及有关jar包详解1.HttpClient 简介HttpClient是ApacheJakartaCommon下的子项目,可以用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。本文首先介绍HTTPClient,然后根据作者实际工作经验给出了一些常见问题的解决方法。HTTP协议可能是现在Internet上使用得最多、最重要的协议了,越来越多的Java应用程序需要直接通过HTTP协议来访问网络资源。虽然在JDK的包中已经提供了访问HTTP协议的基本功能,但是对于大部分应用程序来说,JDK库本身提供的功能还不够丰富和灵活。HttpClient是ApacheJakartaCommon下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的项目中,比如ApacheJakarta上很著名的另外两个开源项目Cactus和HTMLUnit都使用了HttpClient。现在HttpClient最新版本为HttpClient4.0-beta22.HttpClient 功能介绍以下列出的是 HttpClient 提供的主要的功能,要知道更多详细的功能可以参见HttpClient 的主页。(1)实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)2)支持自动转向3)支持HTTPS协议标准文档实用文案(4)支持代理服务器等3.HttpClient 基本功能的使用(1)GET 方法使用 HttpClient 需要以下 6个步骤:1.创建 HttpClient 的实例2.创建某种连接方法的实例, 在这里是 GetMethod 。在GetMethod 的构造函数中传入待连接的地址3.调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 method 实例读response释放连接。无论执行方法是否成功,都必须释放连接对得到后的内容进行处理根据以上步骤,我们来编写用 GET方法来取得某网页内容的代码。大部分情况下 HttpClient 默认的构造函数已经足够使用。 HttpClienthttpClient=newHttpClient();创建GET方法的实例。在 GET方法的构造函数中传入待连接的地址即可。用 GetMethod将会自动处理转发过程,如果想要把自动处理转发过程去掉的话,可以调用方法setFollowRedirects(false) 。GetMethodgetMethod=newGetMethod(".....");调用实例 httpClient 的executeMethod 方法来执行 getMethod 。由于是执行在网络上的程序,在运行 executeMethod 方法的时候,需要处理两个异常,分别是 HttpException 和IOException 。引起第一种异常的原因主要可能是在构造 getMethod 的时候传入的协议不对,比如不小心将 "http" 写成"htp" ,或者服务器端返回的内容不正常等,并且该异常发生是不可恢标准文档实用文案复的;第二种异常一般是由于网络原因引起的异常, 对于这种异常 (IOException ),HttpClient会根据你指定的恢复策略自动试着重新执行 executeMethod 方法。HttpClient 的恢复策略可以自定义(通过实现接口 HttpMethodRetryHandler 来实现)。通过 httpClient 的方法setParameter 设置你实现的恢复策略,本文中使用的是系统提供的默认恢复策略,该策略在碰到第二类异常的时候将自动重试 3次。executeMethod 返回值是一个整数, 表示了执行该方法后服务器返回的状态码, 该状态码能表示出该方法执行是否成功、 需要认证或者页面发生了跳转(默认状态下 GetMethod 的实例是自动处理跳转的)等。 //设置成了默认的恢复策略,在发生异常时候将自动重试 3次,在这里你也可以设置成自定义的恢复策略getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,newDefaultHttpMethodRetryHandler());//执行getMethodintstatusCode=client.executeMethod(getMethod);if(statusCode!=HttpStatus.SC_OK){}在返回的状态码正确后,即可取得内容。取得目标地址的内容有三种方法:第一种,getResponseBody ,该方法返回的是目标的二进制的 byte 流;第二种,getResponseBodyAsString ,这个方法返回的是 String 类型,值得注意的是该方法返回的String 的编码是根据系统默认的编码方式, 所以返回的 String 值可能编码类型有误, 在本文的"字符编码"部分中将对此做详细介绍;第三种, getResponseBodyAsStream ,这个方法对于目标地址中有大量数据需要传输是最佳的。在这里我们使用了最简单的 getResponseBody 方法。byte[]responseBody=method.getResponseBody();标准文档实用文案释放连接。无论执行方法是否成功,都必须释放连接。 method.releaseConnection();处理内容。在这一步中根据你的需要处理内容,在例子中只是简单的将内容打印到控制台。下面是程序的完整代码,这些代码也可在附件中的 test.GetSample 中找到。packagetest;publicclassGetSample{publicstaticvoidmain(String[]args){//构造HttpClient 的实例HttpClienthttpClient=newHttpClient();创建GET方法的实例GetMethodgetMethod=newGetMethod("...");使用系统提供的默认的恢复策略getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,newDefaultHttpMethodRetryHandler());try{//执行getMethodintstatusCode=httpClient.executeMethod(getMethod);if(statusCode!=HttpStatus.SC_OK){标准文档实用文案getMethod.getStatusLine());}读取内容byte[]responseBody=getMethod.getResponseBody();处理内容}catch(HttpExceptione){发生致命的异常,可能是协议不对或者返回的内容有问题e.printStackTrace();}catch(IOExceptione){//发生网络异常e.printStackTrace();}finally{释放连接getMethod.releaseConnection();}}}2)POST方法标准文档实用文案根据RFC2616,对POST的解释如下: POST方法用来向目的服务器发出请求,要求它接受被附在请求后的实体,并把它当作请求队列( Request-Line )中请求 URI所指定资源的附加新子项。POST被设计成用统一的方法实现下列功能:对现有资源的注释( Annotationofexistingresources )向电子公告栏、新闻组,邮件列表或类似讨论组发送消息提交数据块,如将表单的结果提交给数据处理过程通过附加操作来扩展数据库调用HttpClient 中的PostMethod 与GetMethod 类似,除了设置 PostMethod 的实例与GetMethod 有些不同之外,剩下的步骤都差不多。在下面的例子中,省去了与 GetMethod相同的步骤,只说明与上面不同的地方,并以登录清华大学 BBS为例子进行说明。构造PostMethod 之前的步骤都相同,与 GetMethod 一样,构造PostMethod 也需要一个URI参数。在创建了 PostMethod 的实例之后, 需要给method 实例填充表单的值, 在BBS的登录表单中需要有两个域, 第一个是用户名 (域名叫 id),第二个是密码(域名叫 passwd)。表单中的域用类 NameValuePair 来表示,该类的构造函数第一个参数是域名, 第二参数是该域的值;将表单所有的值设置到 PostMethod 中用方法 setRequestBody 。另外由于 BBS登录成功后会转向另外一个页面, 但是HttpClient 对于要求接受后继服务的请求, 比如POST和PUT,不支持自动转发,因此需要自己对页面转向做处理。具体的页面转向处理请参见下面的 "自动转向"部分。代码如下:Stringurl="....";PostMethodpostMethod=newPostMethod(url);//填入各个表单域的值NameValuePair[]data={newNameValuePair("id","youUserName"),标准文档实用文案newNameValuePair("passwd","yourPwd")};// 将表单的值放入 postMethod 中postMethod.setRequestBody(data);执行postMethodintstatusCode=httpClient.executeMethod(postMethod);//HttpClient 对于要求接受后继服务的请求,象 POST和PUT等不能自动处理转发//301 或者302if(statusCode==HttpStatus.SC_MOVED_PERMANENTLY||statusCode==HttpStatus.SC_MOVED_TEMPORARILY){从头中取出转向的地址HeaderlocationHeader=postMethod.getResponseHeader("location");Stringlocation=null;if(locationHeader!=null){location=locationHeader.getValue();}else{}return;}4使用HttpClient 过程中常见的一些问题标准文档实用文案下面介绍在使用 HttpClient 过程中常见的一些问题。字符编码某目标页的编码可能出现在两个地方,第一个地方是服务器返回的 http 头中,另外一个地方是得到的 html/xml 页面中。在http 头的Content-Type 字段可能会包含字符编码信息。例如可能返回的头会包含这样子的信息:Content-Type:text/html;charset=UTF-8 。这个头信息表明该页的编码是 UTF-8,但是服务器返回的头信息未必与内容能匹配上。 比如对于一些双字节语言国家, 可能服务器返回的编码类型是 UTF-8,但真正的内容却不是 UTF-8 编码的,因此需要在另外的地方去得到页面的编码信息;但是如果服务器返回的编码不是 UTF-8,而是具体的一些编码,比如 gb2312 等,那服务器返回的可能是正确的编码信息。通过 method 对象的getResponseCharSet() 方法就可以得到 http 头中的编码信息。对于象 xml或者html 这样的文件,允许作者在页面中直接指定编码类型。比如在 html 中会有<metahttp-equiv="Content-Type"content="text/html;charset=gb2312"/> 这样的标签;或者在 xml中会有<?xmlversion="1.0"encoding="gb2312"?> 这样的标签,在这些情况下,可能与 http 头中返回的编码信息冲突,需要用户自己判断到底那种编码类型应该是真正的编码。自动转向根据RFC2616中对自动转向的定义, 主要有两种:301和302。301表示永久的移走(MovedPermanently ),当返回的是 301,则表示请求的资源已经被移到一个固定的新地方, 任何向该地址发起请求都会被转到新的地址上。 302表示暂时的转向,比如在服务器端的 servlet 程序调用了sendRedirect 方法,则在客户端就会得到一个 302 的代码,这时服务器返回的头信息中location 的值就是 sendRedirect 转向的目标地址。标准文档实用文案HttpClient 支持自动转向处理, 但是象POST和PUT方式这种要求接受后继服务的请求方式,暂时不支持自动转向,因此如果碰到 POST方式提交后返回的是 301或者302的话需要自己处理。就像刚才在 POSTMethod 中举的例子:如果想进入登录 BBS后的页面,必须重新发起登录的请求,请求的地址可以在头字段 location 中得到。不过需要注意的是, 有时候location返回的可能是相对路径, 因此需要对 location 返回的值做一些处理才可以发起向新地址的请求。另外除了在头中包含的信息可能使页面发生重定向外, 在页面中也有可能会发生页面的重定向。引起页面自动转发的标签是: <metahttp-equiv="refresh"content="5;url=...."> 。如果你想在程序中也处理这种情况的话得自己分析页面来实现转向。 需要注意的是,在上面那个标签中url的值也可以是一个相对地址,如果是这样的话,需要对它做一些处理后才可以转发。处理HTTPS协议HttpClient 提供了对 SSL的支持,在使用 SSL之前必须安装 JSSE。在Sun提供的1.4以后的版本中, JSSE已经集成到 JDK中,如果你使用的是 JDK1.4以前的版本则必须安装 JSSE。JSSE不同的厂家有不同的实现。 下面介绍怎么使用 HttpClient 来打开 Https 连接。这里有两种方法可以打开 https 连接,第一种就是得到服务器颁发的证书, 然后导入到本地的 keystore 中;另外一种办法就是通过扩展 HttpClient 的类来实现自动接受证书。方法1,取得证书,并导入本地的 keystore :安装JSSE(如果你使用的 JDK版本是1.4或者1.4以上就可以跳过这一步) 。本文以 IBM的JSSE为例子说明。先到 IBM网站上下载 JSSE的安装包。然后解压开之后将 ibmjsse.jar 包拷贝到 目录下。取得并且导入证书。证书可以通过 IE来获得:1. 用IE打开需要连接的 https 网址,会弹出如下对话框:标准文档实用文案2.单击"ViewCertificate" ,在弹出的对话框中选择 "Details" ,然后再单击"CopytoFile" ,根据提供的向导生成待访问网页的证书文件3.向导第一步,欢迎界面,直接单击"Next",4.向导第二步,选择导出的文件格式,默认,单击"Next",5.向导第三步,输入导出的文件名,输入后,单击"Next",6.向导第四步,单击"Finish",完成向导7.最后弹出一个对话框,显示导出成功用keytool 工具把刚才导出的证书倒入本地 keystore 。Keytool 命令在下,打开命令行窗口,并到 目录下,运行下面的命令:keytool-import-noprompt-keystorecacerts-storepasschangeit-aliasyourEntry1-fileyour.cer其中参数 alias后跟的值是当前证书在 keystore 中的唯一标识符,但是大小写不区分;参数file后跟的是刚才通过 IE导出的证书所在的路径和文件名; 如果你想删除刚才导入到 keystore的证书,可以用命令:keytool-delete-keystorecacerts-storepasschangeit-aliasyourEntry1写程序访问 https 地址。如果想测试是否能连上 https,只需要稍改一下 GetSample 例子,把请求的目标变成一个 https 地址。GetMethodgetMethod=newGetMethod("yoururl");运行该程序可能出现的问题:1.抛出异常 。出现这个异常可能是因为没有加 JSSEProvider ,如果用的是 IBM的JSSEProvider ,在程序中加入这样的一行:标准文档实用文案Security.addProvider(newIBMJSSEProvider());或者也可以打开 <java-home>\lib\security\java.security ,在行后面加入 2.抛出异常 。出现这个异

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论