HttpClient学习
- 格式:doc
- 大小:201.50 KB
- 文档页数:39
异步httpclient(httpasyncclient)的使⽤与总结参考:1. 前⾔应⽤层的⽹络模型有同步与异步。
同步意味当前线程是阻塞的,只有本次请求完成后才能进⾏下⼀次请求;异步意味着所有的请求可以同时塞⼊缓冲区,不阻塞当前的线程;httpclient在4.x之后开始提供基于nio的异步版本httpasyncclient,httpasyncclient借助了Java并发库和nio进⾏封装(虽说NIO是同步⾮阻塞IO,但是HttpAsyncClient提供了回调的机制,与netty类似,所以可以模拟类似于AIO的效果),其调⽤⽅式⾮常便捷,但是其中也有许多需要注意的地⽅。
2. pom⽂件本⽂依赖4.1.2,当前最新的客户端版本是4.1.3maven repository 地址<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.2</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4.5</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore-nio</artifactId><version>4.4.5</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpasyncclient</artifactId><version>4.1.2</version></dependency>12345678910111213141516171819202122233. 简单的实例public class TestHttpClient {public static void main(String[] args){RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(50000).setSocketTimeout(50000).setConnectionRequestTimeout(1000).build();//配置io线程IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setIoThreadCount(Runtime.getRuntime().availableProcessors()).setSoKeepAlive(true).build();//设置连接池⼤⼩ConnectingIOReactor ioReactor=null;try {ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);} catch (IOReactorException e) {e.printStackTrace();}PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager(ioReactor); connManager.setMaxTotal(100);connManager.setDefaultMaxPerRoute(100);final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setConnectionManager(connManager).setDefaultRequestConfig(requestConfig).build();//构造请求String url = "http://127.0.0.1:9200/_bulk";HttpPost httpPost = new HttpPost(url);StringEntity entity = null;try {String a = "{ \"index\": { \"_index\": \"test\", \"_type\": \"test\"} }\n" +"{\"name\": \"上海\",\"age\":33}\n";entity = new StringEntity(a);} catch (UnsupportedEncodingException e) {e.printStackTrace();}httpPost.setEntity(entity);//startclient.start();//异步请求client.execute(httpPost, new Back());while(true){try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}}static class Back implements FutureCallback<HttpResponse>{private long start = System.currentTimeMillis();Back(){}public void completed(HttpResponse httpResponse) {try {System.out.println("cost is:"+(System.currentTimeMillis()-start)+":"+EntityUtils.toString(httpResponse.getEntity())); } catch (IOException e) {e.printStackTrace();}}public void failed(Exception e) {System.err.println(" cost is:"+(System.currentTimeMillis()-start)+":"+e);}public void cancelled() {2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66717273747576777879808182834. ⼏个重要的参数4.1 TimeOut(3个)的设置ConnectTimeout : 连接超时,连接建⽴时间,三次握⼿完成时间。
HttpClient(五)--模拟表单上传⽂件1.maven依赖<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.2</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpmime</artifactId><version>4.5.2</version></dependency>2.代码实现import java.io.File;import java.io.IOException;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.HttpClient;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.mime.MultipartEntityBuilder;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;public class HttpClientUpload {public static void main(String[] args) {// 将 fileUrl 上传到 url中,上传成功后,返回下载地址String url = "http://127.0.0.1:8080/Joe/upload";String fileUrl = "C:/abc.txt";try {System.out.println(post(url, "file", new File(fileUrl)));} catch (Exception e) {e.printStackTrace();}}/*** post:(上传).** @author Joe Date:2017年9⽉11⽇下午5:37:46* @param serverUrl* @param fileParamName* @param file* @return* @throws ClientProtocolException* @throws IOException*/public static String post(String serverUrl, String fileParamName, File file)throws ClientProtocolException, IOException {HttpPost httpPost = new HttpPost(serverUrl);MultipartEntityBuilder builder = MultipartEntityBuilder.create();// 上传的⽂件builder.addBinaryBody(fileParamName, file);HttpEntity httpEntity = builder.build();httpPost.setEntity(httpEntity);// 请求获取数据的超时时间、设置从connect// Manager获取Connection超时时间(因为⽬前版本是可以共享连接池的)、设置连接超时时间RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectionRequestTimeout(3000) .setConnectTimeout(10000).build();httpPost.setConfig(requestConfig);HttpClient httpClient = HttpClients.createDefault();HttpResponse response = httpClient.execute(httpPost);return EntityUtils.toString(response.getEntity());}}。
HttpClient源码分析/*** 此接⼝仅代表HTTP请求执⾏的最基本约定。
* 它对请求执⾏过程没有任何限制或特定的细节,并将状态管理、⾝份验证和重定向处理的细节留给单个实现。
*/public interface HttpClient {HttpResponse execute(HttpUriRequest request);}/*** ⽤于提供创建{@link CloseableHttpClient}实例⼯⼚⽅法.*/public class HttpClients {public static CloseableHttpClient createDefault() {return HttpClientBuilder.create().build();}}/*** HTTP消息包括从客户机到服务器的请求和从服务器到客户机的响应。
* HTTP-message = Request | Response ; HTTP/1.1 messages** {@link HttpRequest} and {@link HttpResponse} 接⼝继承{@link HttpMessage }*/public interface HttpMessage {}/*** 从客户机到服务器的请求消息包括,* 在该消息的第⼀⾏中,要应⽤于该资源的⽅法、资源的标识符以及正在使⽤的协议版本。
* method uri http/1.1*/public interface HttpRequest extends HttpMessage {RequestLine getRequestLine(); // 获取请求⾏}/*** 在接收和解释请求消息后,服务器⽤HTTP响应消息响应。
* 设置/获取状态⾏、状态码、原因短语、实体、locale*/public interface HttpResponse extends HttpMessage {}/*** Extended version of the {@link HttpRequest} interface that provides convenience methods to access request properties such as request URI and method type. * {@link HttpRequest}接⼝的扩展版本,提供访问请求属性(如请求URI和⽅法类型)的⽅便⽅法。
C++使用libcurl做HttpClient当使用C++做HTTP客户端时,目前通用的做法就是使用libcurl。
其官方网站的地址是http://curl.haxx.se/,该网站主要提供了Curl和libcurl。
Curl是命令行工具,用于完成FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及LDAP的命令的请求及接收回馈。
libcurl提供给开发者,用于使用C++跨平台的开发各种网络协议的请求及响应。
里面的文档非常齐全,不过都是英文的。
本文提供最简单的demo使用libcurl开发HttpClient。
主要包括同步的HTTP GET、HTTP POST、HTTPS GET、HTTPS POST。
下载libcurl包,如果使用Linux平台,建议下载源文件编译;如果使用Windows平台,建议下载Win32 - MSVC,下载地址是:http://curl.haxx.se/download.html#ifndef __HTTP_CURL_H__ #define __HTTP_CURL_H__ #include class CHttpClient { public:CHttpClient(void); ~CHttpClient(void); public:/** * @brief HTTP POST请求* @param strUrl 输入参数,请求的Url地址,如: *@param strPost 输入参数,使用如下格式para1=val1?2=val2&… * @param strResponse 输出参数,返回的内容* @return 返回是否Post成功*/ int Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse); /** *@brief HTTP GET请求* @param strUrl 输入参数,请求的Url地址,如: * @param strResponse 输出参数,返回的内容* @return 返回是否Post成功*/ int Get(const std::string & strUrl, std::string & strResponse); /** * @brief HTTPS POST请求,无证书版本* @param strUrl 输入参数,请求的Url地址,如:https:// * @param strPost 输入参数,使用如下格式para1=val1?2=val2&…* @param strResponse 输出参数,返回的内容*@param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性. * @return 返回是否Post成功*/ int Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath = NULL); /** * @brief HTTPS GET请求,无证书版本* @param strUrl 输入参数,请求的Url地址,如:https:// *@param strResponse 输出参数,返回的内容*@param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性. * @return 返回是否Post成功*/ int Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath = NULL); public: void SetDebug(bool bDebug); private: bool m_bDebug; }; #endif [cpp] view plaincopy#include "httpclient.h" #include "curl/curl.h"#include CHttpClient::CHttpClient(void) :m_bDebug(false) { } CHttpClient::~CHttpClient(void) { } static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *) { if(itype == CURLINFO_TEXT){ //printf("[TEXT]%s\n", pData); }else if(itype == CURLINFO_HEADER_IN){ printf("[HEADER_IN]%s\n", pData); } else if(itype == CURLINFO_HEADER_OUT){ printf("[HEADER_OUT]%s\n", pData); } else if(itype == CURLINFO_DATA_IN){ printf("[DATA_IN]%s\n", pData); }else if(itype == CURLINFO_DATA_OUT){ printf("[DATA_OUT]%s\n", pData); } return 0; } static size_t OnWriteData(void* buffer, size_tsize, size_t nmemb, void* lpVoid) { std::string* str = dynamic_caststd::string*>((std::string *)lpVoid);if( NULL == str || NULL == buffer ) { return -1; } char* pData = (char*)buffer;str->append(pData, size * nmemb); return nmemb; } int CHttpClient::Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse){ CURLcode res; CURL* curl = curl_easy_init(); if(NULL == curl) { returnCURLE_FAILED_INIT; } if(m_bDebug){ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl,CURLOPT_DEBUGFUNCTION, OnDebug); }curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());curl_easy_setopt(curl, CURLOPT_POST, 1);curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str()); curl_easy_setopt(curl,CURLOPT_READFUNCTION, NULL);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); curl_easy_setopt(curl,CURLOPT_WRITEDATA, (void *)&strResponse);curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); res = curl_easy_perform(curl);curl_easy_cleanup(curl); return res; } int CHttpClient::Get(const std::string & strUrl, std::string & strResponse) { CURLcode res; CURL* curl = curl_easy_init(); if(NULL == curl){ return CURLE_FAILED_INIT; }if(m_bDebug) { curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); } pre name="code" class="cpp">curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION, OnWriteData);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); /** * 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。
javahttpclient设置超时时间和代理的⽅法设置超时时间设置HttpClient的超时时间,⾮常有必要性,因为httpclient 默认超时时间很长,⾃⼰可以测试⼀下是多久,设置超时时间否则会影响⾃⼰系统的业务逻辑,例如阻塞系统,影响系统的吞吐量,占⽤线程数。
httpclient 4.4版本之后将这些设置封装到 RequestConfig 对象⾥,其中 setConnectTimeout 是设置连接到⽬标 URL 的等待时长,超过这个时间还没连上就抛出连接超时;setConnectionRequestTimeout 是从connect Manager(连接池)获取连接的等待时长,这个版本是共享连接池的;setSocketTimeout 是连接到⽬标URL 之后等待返回响应的时长,即超过这个时间就放弃本次调⽤并抛出SocketTimeoutException:Read Time Outpublic static RequestConfig getRequestConfig(){RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10000).setSocketTimeout(10000).setConnectionRequestTimeout(6000).build(); return requestConfig;}设置代理有时候我们线上访问外部第三⽅的接⼝的时候,不想暴露真实机器的IP,或者我们的机器不能访问外⽹的时候,我们可以通过代理服务器来访问,代理服务器充当内⽹与外⽹链接的中间⼈。
httpclient 4.4后设置代理的 IP、端⼝被封装到 RequestConfig 对象⾥,通过 HttpHost 对象封装代理的 IP、端⼝和协议。
这⾥需要注意的⼀点是,如果你的⽬标 URL 是 HTTP 协议的,那么你的代理也应该是 HTTP 协议的,如下 HttpHost 的构造⽅法可以指定代理服务的协议,不传默认为 HTTP。
httpclient4 中文版帮助文档,最新官方版翻译版前言超文本传输协议(HTTP)也许是当今互联网上使用的最重要的协议了。
Web服务,有网络功能的设备和网络计算的发展,都持续扩展了HTTP协议的角色,超越了用户使用的Web 浏览器范畴,同时,也增加了需要HTTP协议支持的应用程序的数量。
尽管包提供了基本通过HTTP访问资源的功能,但它没有提供全面的灵活性和其它很多应用程序需要的功能。
HttpClient就是寻求弥补这项空白的组件,通过提供一个有效的,保持更新的,功能丰富的软件包来实现客户端最新的HTTP标准和建议。
为扩展而设计,同时为基本的HTTP协议提供强大的支持,HttpClient组件也许就是构建HTTP客户端应用程序,比如web浏览器,web服务端,利用或扩展HTTP协议进行分布式通信的系统的开发人员的关注点。
1. HttpClient的范围基于HttpCore[/httpcomponents-core/index.html]的客户端HTTP运输实现库基于经典(阻塞)I/O内容无关2. 什么是HttpClient不能做的HttpClient 不是一个浏览器。
它是一个客户端的HTTP通信实现库。
HttpClient的目标是发送和接收HTTP报文。
HttpClient不会去缓存内容,执行嵌入在HTML页面中的javascript 代码,猜测内容类型,重新格式化请求/重定向URI,或者其它和HTTP运输无关的功能。
第一章基础1.1 执行请求HttpClient 最重要的功能是执行HTTP方法。
一个HTTP方法的执行包含一个或多个HTTP请求/HTTP响应交换,通常由HttpClient的内部来处理。
而期望用户提供一个要执行的请求对象,而HttpClient期望传输请求到目标服务器并返回对应的响应对象,或者当执行不成功时抛出异常。
很自然地,HttpClient API的主要切入点就是定义描述上述规约的HttpClient接口。
Feign使⽤HttpClient和OkHttp⽅式⽬录使⽤HttpClient和OkHttp使⽤HttpClient使⽤OkHttpOpenFeign替换为OkHttppom中引⼊feign-okhttp在application.yml中配置okhttp使⽤HttpClient和OkHttp在Feign中,Client是⼀个⾮常重要的组件,Feign最终发送Request请求以及接收Response响应都是由Client组件来完成的。
Client在Feign源码中是⼀个接⼝,在默认情况下,Client的实现类是Client.Default。
Client.Default是由HttpURLConnection来实现⽹络请求的。
另外,Client还⽀持HttpClient和OkHttp来进⾏⽹络请求。
⾸先查看FeignRibbonClient的⾃动配置类FeignRibbonClientAutoConfiguration,该类在程序启动的时候注⼊⼀些Bean,其中注⼊了⼀个BeanName为feignClient的Client类型的Bean。
在省缺配置BeanName为FeignClient的Bean的情况下,会⾃动注⼊Client.Default这个对象,跟踪Client.Default源码,Client.Default使⽤的⽹络请求框架是HttpURLConnection,代码如下:public static class Default implements Client {private final SSLSocketFactory sslContextFactory;private final HostnameVerifier hostnameVerifier;public Default(SSLSocketFactory sslContextFactory, HostnameVerifier hostnameVerifier) {this.sslContextFactory = sslContextFactory;this.hostnameVerifier = hostnameVerifier;}public Response execute(Request request, Options options) throws IOException {HttpURLConnection connection = this.convertAndSend(request, options);return this.convertResponse(connection, request);}......//代码省略}这种情况下,由于缺乏连接池的⽀持,在达到⼀定流量的后服务肯定会出问题。
一、HttpClient 功能简介●实现了所有HTTP 的方法(GET,POST,PUT,HEAD,OPTIONS,TRACE)●支持自动转向●支持HTTPS 协议●透明地穿过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协议,源码免费可得二、环境搭建1.HttpClient 3.1 所需的基本jar包:commons-httpclient-3.1.jar,下载地址:/dist/httpcomponents/commons-httpclient/binary/;commons-logging.jar,下载地址:/logging/download_logging.cgi;commons-codec.jar,下载地址:/codec/download_codec.cgi;2.HttpClient 4所需的基本jar包:下载地址:/downloads.cgi;最新版本为4.1.2,且官方不再升级HttpClient3。
三、HttpClient 3.x 基本功能的使用1.使用 HttpClient 需要以下 6 个步骤:●创建HttpClient 的实例●创建某种连接方法的实例,在这里是GetMethod。
WebApi异步请求(HttpClient)还是那⼏句话:学⽆⽌境,精益求精⼗年河东,⼗年河西,莫欺少年穷学历代表你的过去,能⼒代表你的现在,学习代表你的将来废话不多说,直接进⼊正题:今天公司总部要求各个分公司把短信接⼝对接上,所谓的短信接⼝其实就是GET或者Post请求,接到这个任务感觉好Easy。
但是真正写起来,你会发现各种各样的问题,⽐如请求报401错误,报400错误,报..等等各种意想不到的错误!总之,在这个过程中尝试了三个⽅法:第⼀个⽅法如下(由于第⼀个⽅法封装的⽐较多,在此仅仅截图),如下:⼩矩形内得POST⽅法,结果发现报400错误。
紧接着我⼜尝试了第⼆种⽅法(这种⽅法⽐较简单,⼀般的POST请求都可以完成)第⼆种⽅法如下(2014年微信公众号开发中,好多请求我都⽤的这个⽅法):public static string GetPage(string posturl, string postData){//WX_SendNews news = new WX_SendNews();//posturl: news.Posturl;//postData:news.PostData;System.IO.Stream outstream = null;Stream instream = null;StreamReader sr = null;HttpWebResponse response = null;HttpWebRequest request = null;Encoding encoding = Encoding.UTF8;byte[] data = encoding.GetBytes(postData);// 准备请求...try{// 设置参数request = WebRequest.Create(posturl) as HttpWebRequest;CookieContainer cookieContainer = new CookieContainer();request.CookieContainer = cookieContainer;request.AllowAutoRedirect = true;request.Method = "POST";request.ContentType = "application/x-www-form-urlencoded";request.ContentLength = data.Length;outstream = request.GetRequestStream();outstream.Write(data, 0, data.Length);outstream.Close();//发送请求并获取相应回应数据response = request.GetResponse() as HttpWebResponse;//直到request.GetResponse()程序才开始向⽬标⽹页发送Post请求instream = response.GetResponseStream();sr = new StreamReader(instream, encoding);//返回结果⽹页(html)代码string content = sr.ReadToEnd();string err = string.Empty;return content;}catch (Exception ex){string err = ex.Message;return string.Empty;}}View Code结果这个⽅法报401错误。
.NETCore中使⽤HttpClient的正确姿势前⾔为了更⽅便在服务端调⽤ HTTP 请求,微软在 .NET Framework 4.x 的时候引⼊了 HttpClient。
但 HttpClient 有很多严重问题,⼀直饱受诟病,⽐如 InfoQ 的这篇⽂章,吐槽了 HttpClient 不能⽴即关闭连接、性能消耗严重等的问题。
Http协议的重要性相信不⽤我多说了,HttpClient相⽐传统JDK⾃带的URLConnection,增加了易⽤性和灵活性,它不仅是客户端发送Http请求变得容易,⽽且也⽅便了开发⼈员测试接⼝(基于Http协议的),即提⾼了开发的效率,也⽅便提⾼代码的健壮性。
因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深⼊。
.NET Core 2.1 开始引⼊的 HttpClientFactory 解决了 HttpClient 的所有痛点。
有了 HttpClientFactory,我们不需要关⼼如何创建 HttpClient,⼜如何释放它。
通过它可以创建具有特定业务的 HttpClient,⽽且可以很友好的和 DI 容器结合使⽤,更为灵活。
下⾯以 Core 为例介绍 HttpClient 新的三种正确使⽤⽅式。
⼀、直接使⽤⽅式不管是哪种⽅式,都要先注册服务,对于 Core 应⽤则是在 Startup.cs ⽂件的 ConfigureServices 添加如果代码:services.AddHttpClient();然后在 Controller 中通过构造注⼊的试获得 IHttpClientFactory,然后通过它来创建 HttpClient 对象。
⽰例代码:public class ValuesController : BaseController{private readonly IHttpClientFactory _httpClientFactory;public ValuesController(IHttpClientFactory httpClientFactory){_httpClientFactory = httpClientFactory;}[HttpGet]public async Task<ActionResult> Get(){var client = _httpClientFactory.CreateClient();client.BaseAddress = new Uri("");string result = await client.GetStringAsync("/");return Ok(result);}}这种使⽤⽅式适合⼀次性的 HTTP 请求调⽤,弊端是如果多次都要请求 github 的接⼝,那就得写很多重复代码配置HttpClient。
HttpClient 学习笔记笔记一:1、HttpClient的功能1.基于标准,纯正java,实现了http1.0和1.1。
2.在一个可扩展的OO框架内,实现了HTTP的全部方法(GET, POST,PUT, DELETE, HEAD, OPTIONS, and TRACE)3.支持HTTPS(ssl上的HTTP)的加密操作4.透明地穿过HTTP代理建立连接5.通过CONNECT方法,利用通过建立穿过HTTP代理的HTTPS连接6.利用本地Java socket,透明地穿过SOCKS(版本5和4)代理建立连接7.支持利用Basic、Digest和NTLM加密的认证8.支持用于上传大文件的Multi-Part表单POST方法9.插件式安全socket实现,易于使用第三方的解决方案10.连接管理,支持多线程应用,支持设定单个主机总连接和最高连接数量,自动检测和关闭失效连接11.直接将请求信息流送到服务器的端口12.直接读取从服务器的端口送出的应答信息13.支持HTTP/1.0中用KeepAlive和HTTP/1.1中用persistance设置的持久连接14.直接访问由服务器送出的应答代码和头部信息15.可设置连接超时时间16.17.HttpMethods 实现Command Pattern,以允许并行请求或高效连接复用18.遵循the Apache Software License协议,源码免费可得2、预备工作对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/extWindows:%JDK_HOME%\jre\lib\ext4)修改下述目录下的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.Sunsecurity.provider.2=com.sun.rsajca.Provider改为:## List of providers and their preference orders:#security.provider.1=com.sun.crypto.provider.SunJCEsecurity.provider.2=sun.security.provider.Sunsecurity.provider.3=com.sun.rsajca.Providersecurity.provider.4=.ssl.internal.ssl.ProviderHttpClient还要求安装commons-logging,下面跟httpclient一块安装。
3、取得源码cvs -d :pserver:anoncvs@:/home/cvspublic loginpassword: anoncvscvs -d :pserver:anoncvs@:/home/cvspublic checkout jakarta-commons/loggingcvs -d :pserver:anoncvs@:/home/cvspublic checkout jakarta-commons/httpclient编译:cd jakarta-commons/loggingant distcp dis/*.jar ../httpclient/lib/cd ../httpclientant dist4、使用HttpClient编程的基本步聚1.创建HttpClient 的一个实例.2.创建某个方法(DeleteMethod,EntityEnclosingMethod,ExpectContinueMethod,GetMethod,HeadMethod,MultipartPostMethod,OptionsMethod,PostMethod,PutMethod,TraceMethod)的一个实例,一般可用要目标URL为参数。
3.让HttpClient 执行这个方法.4.读取应答信息.5.释放连接.6.处理应答.在执行方法的过程中,有两种异常,一种是HttpRecoverableException,表示偶然性错误发生,一般再试可能成功,另一种是IOException,严重错误。
这儿有这个教程中的一个例程,可以下载。
5、认证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认证时出现错误。
1.从HttpClientAPI的角度来看,NTLM与其它认证方式一样的工作,差别是需要提供'NTCredentials'实例而不是'UsernamePasswordCredentials'(其实,前者只是扩展了后者)2.对NTLM认证,访问空间是连接到的机器的域名,这对多域名主机会有一些麻烦.只有HttpClient连接中指定的域名才是认证用的域名。
建议将realm设为null以使用默认的设置。
3.NTLM只是认证了一个连接而不是一请求,所以每当一个新的连接建立就要进行一次认证,且在认证的过程中保持连接是非常重要的。
因此,NTLM不能同时用于代理认证和服务器认证,也不能用于http1.0连接或服务器不支持持久连接的情况。
6、重定向由于技术限制,以及为保证2.0发布版API的稳定,HttpClient还不能自动处重定向,但对重定向到同一主机、同一端口且采用同一协议的情况HttpClient可以支持。
不能自动的处理的情况,包括需要人工交互的情况,或超出httpclient的能力。
当服务器重定向指令指到不同的主机时,HttpClient只是简单地将重定向状态码作为应答状态。
所有的300到399(包含两端)的返回码,都表示是重定向应答。
常见的有:1.301 永久移动. HttpStatus.SC_MOVED_PERMANENTL Y2.302 临时移动. HttpStatus.SC_MOVED_TEMPORARILY3.303 See Other. HttpStatus.SC_SEE_OTHER4.307 临时重定向. HttpStatus.SC_TEMPORARY_REDIRECT当收到简单的重定向时,程序应从HttpMethod对象中抽取新的URL并将其下载。