Apache HttpClient 4.3开发指南 实现URL重定向

作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszs

一、概述

Apache HttpClient 4系列已经发布很久了,但由于它与HttpClient 3.x版本完全不兼容,以至于业内采用此库的公司较少,在互联网上也少有相关的文档资料分享。

本文旨在写一个简要的Apache HttpClient 4.3开发指南,帮助开发者快速上手Apache HttpClient 4.3.x库。

要注意的是,本文档中的代码在低于HttpClient 4.3版本的地方可能不能运行。

二、开发手册

1、创建HTTP客户端
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. CloseableHttpClient client = HttpClientBuilder.create().build();  

2、发送基本的GET请求
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. instance.execute(new HttpGet(“http://www.baidu.com”));  

3、获取HTTP响应的状态码
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. String url = “http://www.baidu.com”;  
  2. CloseableHttpResponse response = instance.execute(new HttpGet(url));  
  3. assertThat(response.getStatusLine().getStatusCode(), equalTo(200));  

4、获取响应的媒体类型
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. String url = “http://www.baidu.com”;  
  2. CloseableHttpResponse response = instance.execute(new HttpGet(url));  
  3. String contentMimeType = ContentType.getOrDefault(response.getEntity()).getMimeType();  
  4. assertThat(contentMimeType, equalTo(ContentType.TEXT_HTML.getMimeType()));  

5、获取响应的BODY部分
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. String url = “http://www.baidu.com”;  
  2. CloseableHttpResponse response = instance.execute(new HttpGet(url));  
  3. String bodyAsString = EntityUtils.toString(response.getEntity());  
  4. assertThat(bodyAsString, notNullValue());  

6、配置请求的超时设置
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. @Test(expected=SocketTimeoutException.class)  
  2. public void givenLowTimeout_whenExecutingRequestWithTimeout_thenException() throws ClientProtocolException, IOException{  
  3.     RequestConfig requestConfig = RequestConfig.custom()  
  4.     .setConnectionRequestTimeout(50).setConnectTimeout(50)  
  5.     .setSocketTimeout(50).build();  
  6.     HttpGet request = new HttpGet(SAMPLE_URL);  
  7.     request.setConfig(requestConfig);  
  8.     instance.execute(request);  
  9. }  

7、发送POST请求
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. instance.execute(new HttpPost(SAMPLE_URL));  

8、为HTTP请求配置重定向
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. CloseableHttpClient instance = HttpClientBuilder.create().disableRedirectHandling().build();  
  2. CloseableHttpResponse response = instance.execute(new HttpGet(SAMPLE_URL));  
  3. assertThat(reponse.getStatusLine().getStatusCode(), equalTo(301));  

9、配置请求的HEADER部分
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. HttpGet request = new HttpGet(SAMPLE_URL);  
  2. request.addHeader(HttpHeaders.ACCEPT, “application/xml”);  
  3. response = instance.execute(request);  

10、获取响应的HEADER部分
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. CloseableHttpResponse response = instance.execute(new HttpGet(SAMPLE_URL));  
  2. Header[] headers = response.getHeaders(HttpHeaders.CONTENT_TYPE);  
  3. assertThat(headers, not(emptyArray()));  

11、关闭或释放资源
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. response = instance.execute(new HttpGet(SAMPLE_URL));  
  2. try{  
  3.   HttpEntity entity = response.getEntity();  
  4.   if(entity!=null){  
  5. InputStream instream = entity.getContent();  
  6. instream.close();  
  7.   }  
  8. finally{  
  9.   response.close();  
  10. }  

以上内容涵盖了HttpClient 4.3所有常见的需求,供开发者参考。

《用Apache HttpClient实现URL重定向》

作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszs

很多网站都使用了URL重定向技术,把一个原始请求从一个位置路由到另一个位置。原因可能是多方面的,比如域名转发、URL缩写、隐私保护、在同一网站维持相似的域名等。

本文讲述怎样使用Apache HTTPComponents HttpClient实现URL重定向。

本文使用的工具:

1. Apache HttpComponents Client 4.3.1

2. JDK 1.7

1、创建Java项目

项目我命名为HttpClientTest,导入如下JAR包:


2、开发

1)创建和配置CloseableHttpClient

CloseableHttpClient是线程安全的,单个实例可用于处理多个HTTP请求。Http Client会自动处理所有的重定向,除非明确地使用disableAutomaticRetries()关闭自动重定向。

2)使用链接创建HttpGet实例,获取重定向。

3)创建本地HTTP执行上下文HttpClientContext。

4)使用Http Client并传递本地实例HttpClientContext,执行HttpGet请求。

5)成功执行请求后,使用上下文对象来获取所有的重定向位置。

6)关闭响应CloseableHttpResponse,释放资源。

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.ch.net;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.URI;  
  5. import java.util.List;  
  6.   
  7. import org.apache.http.client.ClientProtocolException;  
  8. import org.apache.http.client.config.CookieSpecs;  
  9. import org.apache.http.client.config.RequestConfig;  
  10. import org.apache.http.client.methods.CloseableHttpResponse;  
  11. import org.apache.http.client.methods.HttpGet;  
  12. import org.apache.http.client.protocol.HttpClientContext;  
  13. import org.apache.http.impl.client.CloseableHttpClient;  
  14. import org.apache.http.impl.client.HttpClients;  
  15.   
  16. public class UrlRedirectionDemo {  
  17.     // 浏览器Agent  
  18.     public static String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.151 Safari/535.19";  
  19.       
  20.     // 创建并配置HttpClient  
  21.     private static final CloseableHttpClient httpClient = HttpClients  
  22.             .custom()  
  23.             .setUserAgent(USER_AGENT)  
  24.             .setDefaultRequestConfig(  
  25.                     RequestConfig.custom()  
  26.                             .setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY)  
  27.                             .build()).build();  
  28.       
  29.     /** 
  30.      * 根据给定的链接获取所有的重定向位置 
  31.      * @param link 给定的链接 
  32.      * @return 
  33.      * @throws ClientProtocolException 
  34.      * @throws IOException 
  35.      */  
  36.     public List<URI> getAllRedirectLocations(String link) throws ClientProtocolException, IOException{  
  37.         List<URI> redirectLocations = null;  
  38.         CloseableHttpResponse response = null;  
  39.         try{  
  40.             HttpClientContext context = HttpClientContext.create();  
  41.             HttpGet httpGet = new HttpGet(link);  
  42.             response = httpClient.execute(httpGet, context);  
  43.               
  44.             // 获取所有的重定向位置  
  45.             redirectLocations = context.getRedirectLocations();  
  46.         } finally{  
  47.             if(response!=null){  
  48.                 response.close();  
  49.             }  
  50.         }  
  51.         return redirectLocations;  
  52.     }  
  53.       
  54.     public static void main(String[] args) throws ClientProtocolException, IOException{  
  55.         // 输入URL  
  56.         String link = "http://t.cn/zjYwrl3";  
  57.         UrlRedirectionDemo demo = new UrlRedirectionDemo();  
  58.         List<URI> allRedirectLocations = demo.getAllRedirectLocations(link);  
  59.         if(allRedirectLocations!=null){  
  60.             System.out.println(link);  
  61.             for(URI uri : allRedirectLocations){  
  62.                 System.out.println("|\nv\n" + uri.toASCIIString());  
  63.             }  
  64.         } else{  
  65.             System.out.println("Not found!");  
  66.         }  
  67.     }  
  68. }  

如果使用默认的User-Agent设置,有些网站会返回HTTP 500状态码错误。一旦网站返回200状态码而且返回的HTML的内容是“500 server error”时,为保证兼容性,应该使用标准的Web浏览器的User-Agent字符串。

500 – 服务器内部错误

200 - 服务器成功返回网页

3、运行

我在新浪微博中找了个URL缩短的地址作为输入,执行后,果然找到了重定向地址。

控制台输出为:

[python]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. http://t.cn/zjYwrl3  
  2. |  
  3. v  
  4. http://hero.pongo.cn/  

4、验证

用在线URL重定向检测工具测试:


验证OK。



最近用到了HttpClient写爬虫,可能我有新版本强迫症,老是喜欢用新版本的东西(虽说新版本不一定好用),然后就用了HttpClient 4.3。HttpClient这货和Lucene一样,每个版本的API都变化很大,这有点让人头疼。就好比创建一个HttpClient对象吧,每一个版本的都不一样,

3.X是这样的

1
HttpClient httpClient= new DefaultHttpClient();

4.3是这样的

CloseableHttpClient httpClient = HttpClients.createDefault();


当然,上面这些变化只不过是一些小变化,大家看看API大家就都会了。

我要讲的是超时设置,HttpClient有三种超时设置,最近比较忙,没时间具体归纳总结,以后再补上,我这里就讲一些最简单最易用的超时设置方法。

这是个3.X的超时设置方法

?
1
2
3
HttpClient client = new HttpClient();
client.setConnectionTimeout( 30000 ); 
client.setTimeout( 30000 );
?
1
2
HttpClient httpClient= new HttpClient(); 
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout( 5000 );
4.X版本的超时设置(4.3后已过时)
?
1
2
3
HttpClient httpClient= new DefaultHttpClient();
httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 2000 ); //连接时间
httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 2000 ); //数据传输时间
4.3版本超时设置
?
1
2
3
4
5
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet= new HttpGet( "http://www.baidu.com" );//HTTP Get请求(POST雷同)
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout( 2000 ).setConnectTimeout( 2000 ).build(); //设置请求和传输超时时间
httpGet.setConfig(requestConfig);
httpClient.execute(httpGet); //执行请求
BTW,4.3版本不设置超时的话,一旦服务器没有响应,等待时间N久(>24小时)。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值