参考资料:
http://www.systinet.com/doc/wasp_uddi/uddi/igpreliminary.html
教程中的一个例程,能够下载。
来源:竹笋炒肉
虽然用telnet这样的程序均可把页面取回来,可是在与web服务器的交互中,若是涉及cookie或https或ssl等内容,通常功能相对完备的http客户端仍是很是必要的。IE或NetScape等浏览器确实不错,但是若是为实现持续互动而在程序调用浏览器,我我的认为其中的工做量仍是不小的,这还没考虑版权问题。最好的办法,就是能有一个开源的包,能实现http客户端的功能,供咱们开发的程序调用。httpclient就是这么一个包,我相信可能有比它的实现更好的,但目前我只关注这个。:)
html
下面是nogoop作的功能比较表:
java
Features |
nogoop |
Sun JRE < 1.4.2 |
Sun JRE 1.4.2 |
Innovation |
Apache/Jakarta |
cookies |
|
|
|
X |
X |
plug compatible |
X |
X |
X |
X |
[partial] |
true request output stream |
|
|
|
X |
X |
true response input stream |
X |
|
|
X |
X |
connection keep alive |
X |
X |
X |
X |
X |
connection pool throttling |
X |
|
|
|
X |
connection/request timeout |
X |
|
X [uns] |
X |
X |
idle connection timeout |
X |
|
|
|
X |
pipelining of requests |
|
|
|
X |
|
alternate DNS resolution (dnsjava) |
X |
|
|
|
|
SSL |
X |
X |
X |
X |
X |
basic authentication |
X |
X |
X |
X |
X |
digest authentication |
X |
X |
X |
X |
X |
NTLM authentication |
X |
|
[Windows only] |
|
X |
proxy authentication |
X |
X |
X |
X |
X |
minimum JRE version |
1.2 |
1 |
01年4月2日 |
1.2 |
1.2 |
price |
$499 |
free |
free |
free |
free |
source available |
X |
|
|
X |
X |
diagnostic tracing |
X |
|
|
X |
X |
actively supported |
X |
X |
X |
|
X |
fix turnaround |
fast |
slow |
slow |
none |
medium |
license |
purchase |
Sun JRE |
Sun JRE |
LGPL |
Apache |
一、HttpClient的功能
- 基于标准,纯正java,实现了http1.0和1.1。
- 在一个可扩展的OO框架内,实现了HTTP的所有方法(GET, POST,
PUT, DELETE, HEAD, OPTIONS, and TRACE)
- 支持HTTPS(ssl上的HTTP)的加密操做
- 透明地穿过HTTP代理创建链接
- 经过CONNECT方法,利用经过创建穿过HTTP代理的HTTPS链接
- 利用本地Java socket,透明地穿过SOCKS(版本5和4)代理创建链接
- 支持利用Basic、Digest和NTLM加密的认证
- 支持用于上传大文件的Multi-Part表单POST方法
- 插件式安全socket实现,易于使用第三方的解决方案
- 链接管理,支持多线程应用,支持设定单个主机总链接和最高链接数量,自动检测和关闭失效链接
- 直接将请求信息流送到服务器的端口
- 直接读取从服务器的端口送出的应答信息
- 支持HTTP/1.0中用KeepAlive和HTTP/1.1中用persistance设置的持久链接
- 直接访问由服务器送出的应答代码和头部信息
- 可设置链接超时时间
- HttpMethods 实现Command Pattern,以容许并行请求或高效链接复用
- 遵循the Apache Software License协议,源码免费可得
二、预备工做
对jre1.3.*,若是要HttpClient支持https,则须要下载并安装
jsse和
jce.安装的步骤以下:
1)下载jsse和jce.
2)检查CLASSPATH中没有与jsse和jce相关的jar包
3)将 US_export_policy.jar、local_policy.jar、jsse.jar、jnet.jar、jce1_2_x.jar、sunjce_provider.jar、jcert.jar复制到目录:
UNIX:$JDK_HOME/jre/lib/ext
Windows:%JDK_HOME%\jre\lib\ext
4)修改下述目录下的java.security文件。
UNIX:$JDK_HOME/jre/lib/security/
Windows:%JDK_HOME%\jre\lib\security\
5)
将
#
# List of providers and their preference orders:
#
security.provider.1=sun.security.provider.Sun
security.provider.2=com.sun.rsajca.Provider
改成:
#
# List of providers and their preference orders:
#
security.provider.1=com.sun.crypto.provider.SunJCE
security.provider.2=sun.security.provider.Sun
security.provider.3=com.sun.rsajca.Provider
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
HttpClient还要求安装commons-logging,下面跟httpclient一块安装。
三、取得源码
cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic login
password: anoncvs
cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic checkout jakarta-commons/logging
cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic checkout jakarta-commons/httpclient
编译:
cd jakarta-commons/logging
ant dist
cp dis/*.jar ../httpclient/lib/
cd ../httpclient
ant dist
四、使用HttpClient编程的基本步聚
- 建立 HttpClient 的一个实例.
- 建立某个方法(DeleteMethod,EntityEnclosingMethod,ExpectContinueMethod,GetMethod,HeadMethod,MultipartPostMethod,OptionsMethod,PostMethod,PutMethod,TraceMethod)的一个实例,通常可用要目标URL为参数。
- 让 HttpClient 执行这个方法.
- 读取应答信息.
- 释放链接.
- 处理应答.
在执行方法的过程当中,有两种异常,一种是HttpRecoverableException,表示偶然性错误发生,通常再试可能成功,另外一种是IOException,严重错误。
这儿有这个教程中的一个例程,能够
下载。
下面学习与http客户端相关的认证、重定向等内容。
一、认证
HttpClient三种不一样的认证方案: Basic, Digest and NTLM. 这些方案可用于服务器或代理对客户端的认证,简称服务器认证或代理认证。
1)服务器认证(Server Authentication)
HttpClient处理服务器认证几乎是透明的,仅须要开发人员提供登陆信息(login credentials)。登陆信息保存在HttpState类的实例中,能够经过 setCredentials(String realm, Credentials cred)和getCredentials(String realm)来获取或设置。注意,设定对非特定站点访问所须要的登陆信息,将realm参数置为null. HttpClient内建的自动认证,能够经过HttpMethod类的setDoAuthentication(boolean doAuthentication)方法关闭,并且此次关闭只影响HttpMethod当前的实例。
抢先认证(Preemptive Authentication)能够经过下述方法打开.
client.getState().setAuthenticationPreemptive(true);
在这种模式时,HttpClient会主动将basic认证应答信息传给服务器,即便在某种状况下服务器可能返回认证失败的应答,这样作主要是为了减小链接的创建。为使每一个新建的 HttpState实例都实行抢先认证,能够以下设置系统属性。
setSystemProperty(Authenticator.PREEMPTIVE_PROPERTY, "true");
Httpclient实现的抢先认证遵循rfc2617.
2)代理认证(proxy authentication)
除了登陆信息需单独存放之外,代理认证与服务器认证几乎一致。用 setProxyCredentials(String realm, Credentials cred)和 getProxyCredentials(String realm)设、取登陆信息。
3)认证方案(authentication schemes)
Basic
是HTTP中规定最先的也是最兼容(?)的方案,遗憾的是也是最不安全的一个方案,由于它以明码传送用户名和密码。它要求一个UsernamePasswordCredentials实例,能够指定服务器端的访问空间或采用默认的登陆信息。
Digest
是在HTTP1.1中增长的一个方案,虽然不如Basic获得的软件支持多,但仍是有普遍的使用。Digest方案比Basic方案安全得多,因它根本就不经过网络传送实际的密码,传送的是利用这个密码对从服务器传来的一个随机数(nonce)的加密串。它要求一个UsernamePasswordCredentials实例,能够指定服务器端的访问空间或采用默认的登陆信息。
NTLM
这是HttpClient支持的最复杂的认证协议。它M$设计的一个私有协议,没有公开的规范说明。一开始因为设计的缺陷,NTLM的安全性比Digest差,后来通过一个ServicePack补丁后,安全性则比较Digest高。NTLM须要一个NTCredentials实例. 注意,因为NTLM不使用访问空间(realms)的概念,HttpClient利用服务器的域名做访问空间的名字。还须要注意,提供给NTCredentials的用户名,不要用域名的前缀 - 如: "adrian" 是正确的,而 "DOMAIN\adrian" 则是错的.
NTLM认证的工做机制与basic和digest有很大的差异。这些差异通常由HttpClient处理,但理解这些差异有助避免在使用NTLM认证时出现错误。
- 从HttpClientAPI的角度来看,NTLM与其它认证方式同样的工做,差异是须要提供'NTCredentials'实例而不是'UsernamePasswordCredentials'(其实,前者只是扩展了后者)
- 对NTLM认证,访问空间是链接到的机器的域名,这对多域名主机会有一些麻烦.只有HttpClient链接中指定的域名才是认证用的域名。建议将realm设为null以使用默认的设置。
- NTLM只是认证了一个链接而不是一请求,因此每当一个新的链接创建就要进行一次认证,且在认证的过程当中保持链接是很是重要的。 所以,NTLM不能同时用于代理认证和服务器认证,也不能用于http1.0链接或服务器不支持持久链接的状况。
二、重定向
因为技术限制,以及为保证2.0发布版API的稳定,HttpClient还不能自动处重定向,但对重定向到同一主机、同一端口且采用同一协议的状况HttpClient能够支持。不能自动的处理的状况,包括须要人工交互的状况,或超出httpclient的能力。
当服务器重定向指令指到不一样的主机时,HttpClient只是简单地将重定向状态码做为应答状态。全部的300到399(包含两端)的返回码,都表示是重定向应答。常见的有:
- 301 永久移动. HttpStatus.SC_MOVED_PERMANENTLY
- 302 临时移动. HttpStatus.SC_MOVED_TEMPORARILY
- 303 See Other. HttpStatus.SC_SEE_OTHER
- 307 临时重定向. HttpStatus.SC_TEMPORARY_REDIRECT
当收到简单的重定向时,程序应从HttpMethod对象中抽取新的URL并将其下载。另外,限制一下重定向次数是个好的主意,这能够避免递归循环。新的URL能够从头字段Location中抽取,以下:
String redirectLocation;
Header locationHeader = method.getResponseHeader("location");
if (locationHeader != null) {
redirectLocation = locationHeader.getValue();
} else {
// The response is invalid and did not provide the new location for
// the resource. Report an error or possibly handle the response
// like a 404 Not Found error.
}
特殊重定向:
- 300 多重选择. HttpStatus.SC_MULTIPLE_CHOICES
- 304 没有改动. HttpStatus.SC_NO T_MODIFIED
- 305 使用代理. HttpStatus.SC_USE_PROXY