httpclient学习

httpclient入门:  http://www.ibm.com/developerworks/cn/opensource/os-httpclient/
  httpclient证书导入:http://www.blogjava.net/happytian/archive/2006/12/22/89447.html

httpclient高级认识:http://laohuang.iteye.com/blog/55613

httpclient官方文档:http://hc.apache.org/httpcomponents-client/index.html

httpclient资源关闭:http://www.iteye.com/topic/234759

要注意的有以下几点:
1、httpclient连接后资源释放问题很重要,就跟我们用database connection要释放资源一样。

2、https网站采用ssl加密传输,证书导入要注意。

3、做这样的项目最好先了解下http协义,比如302,301,200,404返回代码的含义(这是最基本的),cookie,session的机制。

4、httpclient的redirect状态默认是自动的,这在很大程度上给开发者很大的方便(如一些授权获得cookie),但是有时要手动管理下,比如

  有时会遇到CircularRedirectException异常,出现这样的情况是因为返回的头文件中location值指向之前重复(端口号可以不同)地址,导致可能会出现死

循环递归重定向,这时可以手动关闭:method.setFollowRedirects(false)

5、有的网站会先判别用户的请求是否是来自浏览器,如不是,则返回不正确的文本,所以用httpclient抓取信息时在头部加入如下信息:

header.put("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.1; SV1; QQDownload 1.7; .NET CLR 1.1.4322; CIBA; .NET CLR
2.0.50727)");

6、当post请求提交数据时要改变默认编码,不然的话提交上去的数据会出现乱码。重写postMethod的setContentCharSet()方法就可以了。

处理request请求返回的文本的通用类:

  1     /*
  2      * HttpRequestProxy.java
  3      *
  4      * Created on November 3, 2008, 9:53 AM
  5      */
  6
  7     package cn.com.mozat.net;
  8
  9     import java.io.BufferedReader;
 10     import java.io.IOException;
 11     import java.io.InputStream;
 12     import java.io.InputStreamReader;
 13     import java.util.HashMap;
 14     import java.util.Iterator;
 15     import java.util.Map;
 16     import java.util.Set;
 17
 18     import org.apache.commons.httpclient.Header;
 19     import org.apache.commons.httpclient.HttpClient;
 20     import org.apache.commons.httpclient.HttpException;
 21     import org.apache.commons.httpclient.HttpMethod;
 22     import org.apache.commons.httpclient.NameValuePair;
 23     import org.apache.commons.httpclient.SimpleHttpConnectionManager;
 24     import org.apache.commons.httpclient.methods.GetMethod;
 25     import org.apache.commons.httpclient.methods.PostMethod;
 26
 27     import cn.com.mozat.exception.CustomException;
 28
 29     /**
 30      *
 31      * @author bird  email:[email protected]
 32      *
 33      * 2008-11-4  09:49:48
 34      */
 35     public class HttpRequestProxy{
 36         //超时间隔
 37         private static int connectTimeOut = 60000;
 38      //让connectionmanager管理httpclientconnection时是否关闭连接
 39         private static boolean alwaysClose = false;
 40      //返回数据编码格式
 41         private String encoding = "UTF-8";
 42
 43         private final HttpClient client = new HttpClient(new SimpleHttpConnectionManager(alwaysClose));
 44
 45         public HttpClient getHttpClient(){
 46             return client;
 47         }
 48
 49         /**
 50          * 用法:
 51          * HttpRequestProxy hrp = new HttpRequestProxy();
 52          * hrp.doRequest("http://www.163.com",null,null,"gbk");
 53          *
 54          * @param url  请求的资源URL
 55          * @param postData  POST请求时form表单封装的数据 没有时传null
 56          * @param header   request请求时附带的头信息(header) 没有时传null
 57          * @param encoding response返回的信息编码格式 没有时传null
 58          * @return  response返回的文本数据
 59          * @throws CustomException
 60          */
 61         public String doRequest(String url,Map postData,Map header,String encoding) throws CustomException{
 62          String responseString = null;
 63          //头部请求信息
 64          Header[] headers = null;
 65          if(header != null){
 66           Set entrySet = header.entrySet();
 67              int dataLength = entrySet.size();
 68               headers= new Header[dataLength];
 69              int i = 0;
 70              for(Iterator itor = entrySet.iterator();itor.hasNext();){
 71               Map.Entry entry = (Map.Entry)itor.next();
 72               headers[i++] = new Header(entry.getKey().toString(),entry.getValue().toString());
 73              }
 74          }
 75          //post方式
 76             if(postData!=null){
 77              PostMethod postRequest = new PostMethod(url.trim());
 78              if(headers != null){
 79               for(int i = 0;i < headers.length;i++){
 80                postRequest.setRequestHeader(headers[i]);
 81               }
 82              }
 83              Set entrySet = postData.entrySet();
 84              int dataLength = entrySet.size();
 85              NameValuePair[] params = new NameValuePair[dataLength];
 86              int i = 0;
 87              for(Iterator itor = entrySet.iterator();itor.hasNext();){
 88               Map.Entry entry = (Map.Entry)itor.next();
 89               params[i++] = new NameValuePair(entry.getKey().toString(),entry.getValue().toString());
 90              }
 91              postRequest.setRequestBody(params);
 92              try {
 93         responseString = this.executeMethod(postRequest,encoding);
 94        } catch (CustomException e) {
 95         throw e;
 96        } finally{
 97         postRequest.releaseConnection();
 98        }
 99             }
100           //get方式
101             if(postData == null){
102              GetMethod getRequest = new GetMethod(url.trim());
103              if(headers != null){
104               for(int i = 0;i < headers.length;i++){
105                getRequest.setRequestHeader(headers[i]);
106               }
107              }
108              try {
109         responseString = this.executeMethod(getRequest,encoding);
110        } catch (CustomException e) {
111                     e.printStackTrace();
112         throw e;
113        }finally{
114         getRequest.releaseConnection();
115        }
116             }
117
118             return responseString;
119         }
120
121      private String executeMethod(HttpMethod request, String encoding) throws CustomException{
122       String responseContent = null;
123       InputStream responseStream = null;
124       BufferedReader rd = null;
125       try {
126        this.getHttpClient().executeMethod(request);
127        if(encoding != null){
128         responseStream = request.getResponseBodyAsStream();
129          rd = new BufferedReader(new InputStreamReader(responseStream,
130                           encoding));
131                   String tempLine = rd.readLine();
132                   StringBuffer tempStr = new StringBuffer();
133                   String crlf=System.getProperty("line.separator");
134                   while (tempLine != null)
135                   {
136                       tempStr.append(tempLine);
137                       tempStr.append(crlf);
138                       tempLine = rd.readLine();
139                   }
140                   responseContent = tempStr.toString();
141        }else
142         responseContent = request.getResponseBodyAsString();
143
144        Header locationHeader = request.getResponseHeader("location");
145        //返回代码为302,301时,表示页面己经重定向,则重新请求location的url,这在
146        //一些登录授权取cookie时很重要
147        if (locationHeader != null) {
148                  String redirectUrl = locationHeader.getValue();
149                  this.doRequest(redirectUrl, null, null,null);
150              }
151       } catch (HttpException e) {
152        throw new CustomException(e.getMessage());
153       } catch (IOException e) {
154        throw new CustomException(e.getMessage());
155
156       } finally{
157        if(rd != null)
158         try {
159          rd.close();
160         } catch (IOException e) {
161          throw new CustomException(e.getMessage());
162         }
163         if(responseStream != null)
164          try {
165           responseStream.close();
166          } catch (IOException e) {
167           throw new CustomException(e.getMessage());
168
169          }
170       }
171       return responseContent;
172      }
173
174
175      /**
176       * 特殊请求数据,这样的请求往往会出现redirect本身而出现递归死循环重定向
177       * 所以单独写成一个请求方法
178       * 比如现在请求的url为:http://localhost:8080/demo/index.jsp
179       * 返回代码为302 头部信息中location值为:http://localhost:8083/demo/index.jsp
180       * 这时httpclient认为进入递归死循环重定向,抛出CircularRedirectException异常
181       * @param url
182       * @return
183       * @throws CustomException
184       */
185      public String doSpecialRequest(String url,int count,String encoding) throws CustomException{
186       String str = null;
187       InputStream responseStream = null;
188       BufferedReader rd = null;
189       GetMethod getRequest = new GetMethod(url);
190       //关闭httpclient自动重定向动能
191       getRequest.setFollowRedirects(false);
192       try {
193
194        this.client.executeMethod(getRequest);
195        Header header = getRequest.getResponseHeader("location");
196        if(header!= null){
197         //请求重定向后的URL,count同时加1
198         this.doSpecialRequest(header.getValue(),count+1, encoding);
199        }
200        //这里用count作为标志位,当count为0时才返回请求的URL文本,
201        //这样就可以忽略所有的递归重定向时返回文本流操作,提高性能
202        if(count == 0){
203         getRequest = new GetMethod(url);
204         getRequest.setFollowRedirects(false);
205         this.client.executeMethod(getRequest);
206         responseStream = getRequest.getResponseBodyAsStream();
207         rd = new BufferedReader(new InputStreamReader(responseStream,
208                           encoding));
209                  String tempLine = rd.readLine();
210                  StringBuffer tempStr = new StringBuffer();
211                  String crlf=System.getProperty("line.separator");
212                  while (tempLine != null)
213                  {
214                      tempStr.append(tempLine);
215                      tempStr.append(crlf);
216                      tempLine = rd.readLine();
217                  }
218                  str = tempStr.toString();
219        }
220
221       } catch (HttpException e) {
222        throw new CustomException(e.getMessage());
223       } catch (IOException e) {
224        throw new CustomException(e.getMessage());
225       } finally{
226        getRequest.releaseConnection();
227        if(rd !=null)
228         try {
229          rd.close();
230         } catch (IOException e) {
231          throw new CustomException(e.getMessage());
232         }
233         if(responseStream !=null)
234          try {
235           responseStream.close();
236          } catch (IOException e) {
237           throw new CustomException(e.getMessage());
238          }
239       }
240       return str;
241      }
242
243
244
245
246      public static void main(String[] args) throws Exception{
247       HttpRequestProxy hrp = new HttpRequestProxy();
248        Map header = new HashMap();
249              header.put("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 1.7; .NET CLR 1.1.4322; CIBA; .NET CLR 2.0.50727)");
250       String str = hrp.doRequest(
251         "http://www.cma-cgm.com/en/eBusiness/Tracking/Default.aspx?BolNumber=GZ2108827",
252          null, header,null);
253       System.out.println(str.contains("row_CRXU1587647"));
254     //  System.out.println(str);
255      }
256
257     }  
时间: 2024-10-11 10:11:40

httpclient学习的相关文章

HttpClient学习整理

HttpClient简介 HttpClient 功能介绍     1. 读取网页(HTTP/HTTPS)内容     2.使用POST方式提交数据(httpClient3)     3. 处理页面重定向     4. 模拟登录开心网     5. 提交XML格式参数     6. 访问启用认证的页面     7. 多线程模式下使用httpclient httpClient完整封装 HttpClient简介 HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Ja

HttpClient 学习整理 (转)

source:http://www.blogjava.net/Alpha/archive/2007/01/22/95216.html HttpClient 是我最近想研究的东西,以前想过的一些应用没能有很好的实现,发现这个开源项目之后就有点眉目了,令人头痛的cookie问题还是有办法解决滴.在网上整理了一些东西,写得很好,寄放在这里. HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK

HttpClient 学习整理【转】

转自 http://www.blogjava.net/Alpha/archive/2007/01/22/95216.html HttpClient 是我最近想研究的东西,以前想过的一些应用没能有很好的实现,发现这个开源项目之后就有点眉目了,令人头痛的cookie问题还是有办法解决滴.在网上整理了一些东西,写得很好,寄放在这里.HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK 的 ja

httpclient学习记录

---恢复内容开始--- 此随笔都是一些网上的小实例,我学习后,添上一些注释.菜鸡程序员,水平较低,如有问题请指出. httpclient是一种封装好的http协议的工具包,相对于httpconection来说,会比较简单,功能更多. HttpClient有两个重要方法,一个post,一个get,顾名思义一个是用来发送数据,得到返回值,一个是直接请求地址得到返回值. 下面是几个post和get的实例: 1.get小实例. public class GGGGGG { public String d

Java4Android之httpclient学习与应用

在Java开发中,不可避免的需要和http打交道.而无论我司的迅雷动漫还是我主导的"搜芽"android客户端开发,都需要使用到http和服务器打交道..虽然Java也提供了http的接口,但据我了解,更多的公司都是使用Apache的httpclient来进行开发,不仅因为它灵活强大,而且便捷. 今天,我们学习httpclient的基础知识. 关于Http的基础,在此就不再复习了.建议大家去看一本权威制作<HTTP权威指南>,加个略贵,109元人民币,不过,我买了,因为经典

httpclient 学习

Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性,它不仅是客户端发送Http请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性.因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入. 一.简介 HttpClient是Apache Jakarta Common下的子项目,用来提供高效的.最新的.功能丰

HttpClient 学习记录 (二)

1.message header (header)包含了一些消息头的属性,如:Content length ,content type 下面是同过response 简单获取header: 另外一种获取方式是以迭代器的方式:使用HeaderIterator接口来获取header 提供了一些方便的方法去格式化http消息头,看上去更直观: HttpEntity:从服务器返回的数据类容,除去头部消息: Httpclient只能辨别三种Entity: Streamed:流形势的,一般是从response

httpclient学习(原创)

--httpmime-4.2.5.jar  跟提交Form相关的类 这一块主要post数据的提交.每一条数据同name和content组成.content可能是字节数组或是流.提交这一类(MIME)的数据的时候,还要添加一些 header数据.于是FormBodyPart类就诞生了,它的属性有name,header,content.很多个FormBodyPart组成了HttpMultipart(因为HttpMultipart 有个FormBodyPart的List集合).所有的东东最后在Mult

Java接口自动化测试之HTTPClient学习(四)

pom.xml  文件中dependency 1 <dependencies> 2 <dependency> 3 <groupId>org.testng</groupId> 4 <artifactId>testng</artifactId> 5 <version>6.14.3</version> 6 </dependency> 7 <dependency> 8 <groupId&g