httpclient是apache的一个项目:http://hc.apache.org/
文档比較完好:http://hc.apache.org/httpcomponents-client-ga/tutorial/html/
这里就不啰嗦了,主要是在做demo的时候遇到的一些问题在这里总结一下:
[引用请注明出处http://blog.csdn.net/bhq2010/article/details/9210007]
虽说http协议时无连接的,但毕竟是基于tcp的,底层还是须要和server建立连接的。对于须要从同一个网站抓取大量网页的程序,应该使用连接池,否则每次抓取都和Web网站建立连接、发送请求、获得响应、释放连接,一方面效率不高,还有一方面稍不小心就会疏忽了某些资源的释放、导致网站拒绝连接(非常多网站会拒绝同一个ip的大量连接、防止DOS攻击)。
连接池的例程例如以下:
SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); schemeRegistry.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); PoolingClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry); cm.setMaxTotal(200); cm.setDefaultMaxPerRoute(2); HttpHost googleResearch = new HttpHost("research.google.com", 80); HttpHost wikipediaEn = new HttpHost("en.wikipedia.org", 80); cm.setMaxPerRoute(new HttpRoute(googleResearch), 30); cm.setMaxPerRoute(new HttpRoute(wikipediaEn), 50); SchemaRegistry的作用是注冊协议的默认port号。PoolingClientConnectionManager是池化连接管理器,即连接池,setMaxTotal设置连接池的最大连接数,setDefaultMaxPerRoute设置每一个路由( http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d5e467)上的默认连接个数,setMaxPerRoute则单独为某个网站设置最大连接个数。从连接池中获取http client也非常方面:
DefaultHttpClient client = new DefaultHttpClient(cm);HttpClient须要设置合适的參数,才干更好地工作。默认的參数可以应付少量的抓取工作,但找到一组合适的參数往往能改善特定情况下的抓取效果。设置參数的例程例如以下:
DefaultHttpClient client = new DefaultHttpClient(cm); Integer socketTimeout = 10000; Integer connectionTimeout = 10000; final int retryTime = 3; client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, socketTimeout); client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectionTimeout); client.getParams().setParameter(CoreConnectionPNames.TCP_NODELAY, false); client.getParams().setParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 1024 * 1024); HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() { @Override public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { if (executionCount >= retryTime) { // Do not retry if over max retry count return false; } if (exception instanceof InterruptedIOException) { // Timeout return false; } if (exception instanceof UnknownHostException) { // Unknown host return false; } if (exception instanceof ConnectException) { // Connection refused return false; } if (exception instanceof SSLException) { // SSL handshake exception return false; } HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST); boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); if (idempotent) { // Retry if the request is considered idempotent return true; } return false; } }; client.setHttpRequestRetryHandler(myRetryHandler); 5、6行分别设置了Socket最大等待时间、连接最大等待时间(单位都是毫秒)。socket等待时间是指从网站下载页面和数据时,两个数据包之间的最大时间间隔,超过这个时间间隔,httpclient就觉得连接出了故障。连接最大等待时间则是指和网站建立连接时的最大等待时间,超过这个时间网站不给回应,则觉得网站无法连接。第7行设置httpclient不使用NoDelay策略。假设启用了NoDelay策略,httpclient和网站之间数据传输时将会尽可能及时地将发送缓冲区中的数据发送出去、而不考虑网络带宽的利用率,这个策略适合对实时性要求高的场景。而禁用了这个策略之后,数据传输会採用Nagle's algorithm发送数据,该算法会充分顾及带宽的利用率,而不是传输数据的实时性。第8行设置socket缓冲区的大小(单位为字节),默认是8KB。 HttpRequestRetryHandler是负责处理请求重试的接口。在该接口的内部类中实现RetryRequest方法就可以。当httpclient发送请求之后出现异常时,就会调用这种方法。在该方法中依据已运行请求的次数、请求内容、异常信息推断是否继续重试,若继续重试返回true,否则返回false。转载于:https://www.cnblogs.com/bhlsheji/p/4049998.html
