HttpClient4.5版本中文API
283简单连接管理器.... 284连接池管理器 .27 285连接管理器关闭 28 29连接管理参数 2.10多线程执行请求 29 2.11连接收回策略.... ·,着 30 212连接保持活动的策咯 第三章HTTP状态管理... 3.1 htTp cookies 311 Cookie版本 ∴33 32 Coo kie规范....... 34 33 Http cookie和状态管理参数 35 34 Coo kie规范注册表 35选择 cookie策略 3.6定訇 cookie策略∴.....36 3.7C00ke持久化 36 38HTTP状态管理和执行上下文... ∴37 39每个用户/线程的状态管理, ,37 第四章HTTP认证 39 41用户凭证 ..:.:::·· 4,2认证模式. 39 4.3HTTP认让参数... .:::.:::::::::.::::·::.:.:::::::::: 44认证模式汴册表 45凭据提供器 4.6HTTP认证和执行上卜文 着音看·,看 ·:..:.....:.:::::.::.::..:.:::.:.:. 41 4.7抢占认证 4.8NTLM认证.....................11111243 481NTLM连接持久化. 第五章HTTP客户端服务. 5.1 Httpclient门面 a:.:.::::::::::.:::a::. 45 5.2 Httpclient参数. 5.3自动重定向处理 46 54HTTP客户端和执行上下文 47 第六章高级主题 48 61自定义客户端连接 4 62有状态的HTTP连接 49 621用户令牌处理器 49 22用户令牌和执行上下文 .50 前言 超文木传输协议(HTP)也许是当今互联网上使用的最重要的协议了。Web服务,有 网络功能的设备和网终计算的发展,都持续扩展了HTTP协议的角色,超越了用户使用的 Web浏览器范畴,同时,也增加了需要HTTP协议支持的应用程序的数量。 尽管Javanet包提供」基本通过HTTP访问资源的功能,但它没有提供全面的灭活性和 其它很多应用程序需要的功能。 Httpclient就是寻求弥补这项空白的组件,通过提供一个有 效的,保持史新的,功能丰富的软件包来实现客户端最新的HTTP标准和建议。 为扩展而设计,同时为基本的HTP协议提供强大的支持, Htt cLient组件也许就是构建 HTTP客户端应用程序,比如web浏览器,web服务端,利用或扩展HTTP协议进行分布式 通信的系统的开发人员的关注点。 1. Http client的范围 基于 Httpcore[ ]的客户端HTP 运输实现库 基于经典(阳塞)o 内容无关 2什么是 Httpclien不能做的 Httpclient不是一个浏览器。它是一个客户端的HTP通信实现库。 Httpclient的目 标是发送和接收HTTP报文,Httpclient不会去缓存内容,执行嵌入在HTML页面中 的javascript代码,猜测内容类型,重新格式化请求/重定向UR|,或者其它和HTTP 运输无关的功能 关于翻译 本文档翻泽工作由南磊完成,版权归译者所有。免费发布,但是不可擅自用于任何与商 业有关的用途。若对翻译质量有任何意见或建议,可以联系译者nane1987@gmail.com。 英文原版由 oleg KaInichevs ki所著,若对 Httpclient本身有问题的可以直接反馈到 Apache官 网 Httpclient项目组 第一章基础 11执行请求 Httpclient最重要的功能是执行HTP方法。一个HTTP方法的执行包含一个或多个HTTP 请求/HTP响应交换,通常由 Httpclient的内部来处理。而期望用户提供个要执行的请求 对象,而 Httpclient期望传输请求到目标服务器并返回对应的响应对象,或者当执行不成功 时抛出异常。 很自然地, Httpclient Apl的主要切入点就是定义描述上述规约的 Httpclient接∏ 这里有一个很简单的请求执行过程的示例 Httpclientattpclient-newdefaulthttpciient()i HttpgethttpgetnewHttpget("http://Localhost/)i Httpresponseresponse=httpclient.execute(httpget)i Httpentity entity = response. getentity(i if (entity ! null)[ Inputstream instream entity getcontent()i nt l byte[] tmp- new byte [2048]i while ((i=instream. read(tmp))!=-1 111HTP请求 所有HTTP请求有一个组合了方法名,请求UR和HTTP协议版本的请求行。 Httpclient支持所有定义在HTTP/11版本中的HTTP方法:GET,HEAD,POST,PU,DELETE, TRACE和 OPTIONS。对于每个方法类型都有一个特殊的类: trgEt,nttp:ead, IlttpFost Httpput, Httpdelete, Httptrace Nl Httpoptions 请求的UR是统一资源定位符,它标识了应用于哪个请求之上的资源。HTTP请求UR 包含一个协议模式,主机名称,可选的端口,资源路径,可选的査询和可选的片段。 Httpgethttpget=newHttpget( http://www.google.com/search?nl=en&g=httpclient&btng=google +Search&ag=f&og=) Httpclient提供很多工具方法来简化创建和修改执行UR UR|也可以编程来拼装 Uriuri=uriutils.createuri(nttp,www.googlecom,-l, I'/search", g-attpclient&btnG==Google+Search&ag=f&oq=r null)i Httpgethttpget=newHttpget(uri) Systemoutprintln(httpget.geturi() 输出内容为: http://www.googlecom/search?q=httpclient&btng=google+seaRch &ag-f&oq- 查询字符串也可以从独立的参数中来生成: List params- new Arraylist(i gparams. addnew Basicnamevaluepair("g,hTtpclient))i params. add (new BasicNameValuePair(btng", Google Search"))i params. add(new BasicNamevaluePair(ag",f))i params. add (new BasicNameValuePair( og", null))i Uriuri-uriutils.createuri(http,www.googlecom",-1, search URLEncodedUtils. format (params, UTE-8 ), null HttpgethttpgetnewHttpget(uri)i Systemoutprintln(httpget.geturi()) 输出内容为: http://www.googlecom/search?q-httpclientabtng-gcogle+search &aq=f&oc 112HTP响应 HTTP响应是由服务器在接收和解释请求报文之后返回发送给客户端的报文。响应报文 的第一行包含了协议版本,之后是数字状态码和相关联的文本段。 Httpresponse response new Basichttpresponse(httpvErsion.Http11, Httpstatus. Sc Ok,ok)i System. out. println(response. getProtocolVversion())i System. out. println(response. getstatusLine(). getstatus Code ())i System. out. println(response. getstatusLine(). getReasonPhrase())i System. out. printIn(response. getstatusline().tostring()) 输出内容为: Http/1.1 200 ○K Http/1.1 200 ok 113处理报文头部 个HTP报文可以包含很多描述如内容长度,内容类型等信息属性的头部信息。 Httpclient提供获取,添加,移除和枚举头部信息的方法。 Httpresponse response new Basichttpresponse(httpvErsion.http11, Httpstatus. Sc Ok,ok)i response. addHeader("Set-Cookie", cl=ai path=/i domain=localhost") response. addHeader(set-Cookie, c2=b; path=\"/", c3=ci domain=\"localhost\"")i Header hl = response. getFirstHeader("Set-Cookie)i System. out. println(n1)i Header h2 response getlastHeader("Set-Ccokie")i System. out. printIn(h2)i Header[ hs= response. getHeaders( Set-Cookie)i System. out. println(as length) 输出内容为 Set-Cookie: cl=a; path=/; domain=localhost Set-Cockie: c2=b; path=,, C3=ci domain=localhost 获得给定类型的所有头部信息最有效的方式是使用 Headeriterator接口。 Httpresponse response new Basichttpresponse(httpvErsion.httpI Httpstatus. Sc Ok,ok)i response. addHeader(Set-Cookie, cl=ai path=/; domain=localhost")i response. addHeader(Set-Cookie", "c2=b;path=、"/\",c3=c; domain=\"1 ocala。st、"") HeaderIterator it= response. headeriterator(Set-Cookie") hi1e(it. hasNe×t()){ System. out. println(it. next ())i 输出内容为: Set-Cockie: cl-a; path=/; domain=localhost Set-Cockie: c2=b, path="/, c3=c, domain=loca. 它也提供解析HTTP报文到独立头部信息元素的方法方法 Httpresponse response=new Basichttpresponse(httpvErsion.htTp11 Httpstatus. sc ok,ok)i response. addHeader(Set-Cookie", "cl-a; path-/, domain-localhost"); response. addHeader("Set-Cockie", c2=b; path=\"/", c3=c; domain=\"localhost\"") HeaderElementiterator it new BasicHeaderelementiterator( response. headerIterator("Set-Cookie") Whi1e(it. hasNe×t()) eader⊥ ement e⊥em=it. nextElement() System. out. println(elem. getName()+ elem. getvalue())i NameValuePair[] params elem getParameters()i for (int i =0;i< paramslength; i++)i System. out. printin(+ params[i]) 输出内容为: path-/ domain=localhost c2=b path=/ domain=localhost 114HTTP实体 HTTP报文可以携带和请求或响应相关的内容实体。实体可以在一些请求和响应中求到, 因为它们也是可选的。使用了实体的请求被称为封闭实体请求。HTTP规范定义了两种封闭 实体的方法:POsT和PUT。响应通常期望包含一个内容实体。这个规则也有特例,比如 HEAD方法的响应和204 No Content,304 Not Modified和205 Reset Content 响应。 Httpclient根据其内容出自何处区分三种类型的实体: 流式:内容从流中获得,或者在运行中产生。特别是这种分类包含从HTP 响应中获取的实体。流式实体是不可重复生成的 自我包含式:内容在内存中或通过独立的连接或其它实体中获得 自我包含式的灾体是可以重复生成的。这种类型的实体会经常用于封闭HTTP请求 的实体。 包装式:内容从另外一个实体中获得。 当从一个HTTP响应中获取流式内容时,这个区别对于连接管理很重要。对于由应用稈 序创建而且只使用 Httpclient发送的诮求实体,流式和自我包含式的不同就不那么重要了。 这种情况下,建议考虐如流式这和不能重复的实体,和可以重复的自我包含式实体。 1141重复实体 实体可以重复,意味着它的内容可以被多次读取。这就仅仅是自我包含式的实体∫(像 BytearrayEntity或 Stringently)。 114.2使用HTTP实体 因为一个实体既可以代表二进制内容又可以代表字符内容,它也支持字符编码(支持后 者也就是字符内容)。 实体是当使用封闭内容执行请求,或当请求已经成功执行,或当响应体结果发功到客户 端时创建的。 要从实体中读取内容,可以通过 Httpentityt getcontent()方法从输入流中获取: 这会返回一个java.i°. Input stream对象,或者提供一个输出流到 Httpentity# writeto( Outputstream)方法中,这会一次返回所有写入到给定流中 的内容。 当实体通过一个收到的报文获取时, Httpentity# getcontentfype()方法和 Httpentity t getcontentlenGth()方法可以用来读取通用的元数据,如 Content-ype和 Content- Length头部信息(如果它们是可用的)。因为头部信息 Content-ype可以包含对文本MME类型的字符编码,比如text/ plain或text/html, HttpentitytgetcoNtent eNcoding(方法用米读取这个信息。女果头部信息不可用,那么就 返回长度1,而对于内容类型返回NULL。如果头部信息 Content-ype是可用的,那么 就会返回一个 Header对象。 当为一个传出报文创建实体时,这个元数据不得不通过实体创建器来提供。 StringEntity myEntity new StringEntity ("important mes sage "UTF-8") System. out. println(myEntity getContentType())i System. out. println(myEntity getContentleng th())i System. out. println(entityUtils getContentcharset(myEntity))i System. out. printin (EntityUtils tostring(myEntity))i System. out. println(EntityUtils. toByteArray(myEntity)length)i 输出内容为 Content-Type: text/plain; charset=UTF-8 UTE-8 important message 17 115确保低级别资源释放 当完成一个响应实体,那么保证所有实体内容已经被完全消耗是很重要的,所以连接可 以安仝的放回到连接池中,而且可以通过连接管理器对后续的请求重用连接。处理这个操作 的最方便的方法是调用 Httpentity# consume content()方法米消耗流中的任意可用 内容。 Httpclient探测到内容流尾部已经到达后,会立即会自动释放低层连接,并放回到连 接管理器。 Httpentity# consumecontent()方法调用多次也是安全的。 也可能会有特殊情况,当整个响应内容的小部分需要获取,消耗剩余内容而损失性能, 还有重用连接的代价太高,则可以仅仅通过调用 Httpurirequest# abort()方法来中 止请求。 Httpgethttpget=newHttpget("http://localhost/")i Httpresponseresponse=httpclient.execute(httpget)i Httpentity entity = response getentity()i if (entity =null) i Inputstream instream entity getContent() int byteone instream read(i int byte Two instream read(i // Do not need the rest nttpget. abort ( 连接不会被重用,但是由它持有的所有级别的资源将会被正确释放。 116消耗实体内容 推荐消耗实体内容的方式是使用它的Htp3 ntity# getContent()或 Httpentitytwriteto( Outputstream)方法。 Httpclient也自带 Entityuti-s类, 这会暴露出一些静态方法,这些方法可以更加容易地从实体中读取内容或信息。代替直接读 取java.io. Inputstream,也可以使用这个类中的方法以宇符串/字节数组的形式获取 整个内容体。然而, Entityuti1s的使用是强烈不鼓励的,除非响应实体源自可靠的HTP 服务器和已知的长度限制 Httpgethttpget=newHttpget("http://Localhost/") Httpresponseresponse=httpclient.execute(httpget Httpentity entity response getentity()i f entity null) i long len entity. getContentlength()i if (len !=-1 & len 2048)1 System. out. printIn(EntityUtils. tostring(entity))i f else l / Stream content out 在一些情况下可能会不止一次的读取实体。此时实体内容必须以某种方式在内存或磁盘 上被缓冲起来。最简单的方法是通过使用Bufferedhttpentity类来包装源实体完成。 这会引起源实体内容被读取到内存的缓冲区中。在其它所有方式中,实体包装器将会得到源 实体
用户评论