转自:http://resolute.javaeye.com/blog/491701

commons-httpclient是apache下的一个开源项目,提供了一个纯java实现的http客户端。使用它能够非常方便发送HTTP请求,接受HTTP应答,自己主动管理Cookie等等。 



对于contact-list类库来说,须要使用的功能有,自己主动管理Cookie,设置HTTP头。发送HTTP请求,接受HTTP应答,转发HTTP重定向,还有输出HTTP请求/应答日志,以下对这些功能的实现进行解释: 



1. 自己主动管理Cookie 

view source 

print? 

1.public EmailImporter(String email, String password, String encoding) { 

2.    ...... 

3.    client = new HttpClient(); 

4.    client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); 

5.    client.getParams().setParameter("http.protocol.single-cookie-header", true); 

6.} 



当中将HttpClient的Cookie策略设置为CookiePolicy.BROWSER_COMPATIBILITY,即表示java client将依照浏览器的方式来自己主动处理Cookie。当然你也能够在执行过程中手动调整cookie。比方: 



hotmail登录之前须要设置当前时间的Cookie: 

view source 

print? 

1.client.getState().addCookie(new Cookie("login.live.com", "CkTst", "G" + new Date().getTime())); 



只是,httpclient似乎没有提供删除cookie的功能,于是我添加了两个cookie管理的接口。一个是保留指定的cookies,一个是删除指定的cookies: 

view source 

print?

01.protected void retainCookies(String[] cookieNames) { 

02.    Cookie[] cookies = client.getState().getCookies(); 

03.    ArrayList<Cookie> retainCookies = new ArrayList<Cookie>(); 

04.    for (Cookie cookie : cookies) { 

05.        if (Arrays.binarySearch(cookieNames, cookie.getName()) >= 0) { 

06.            retainCookies.add(cookie); 

07.        } 

08.    } 

09.    client.getState().clearCookies(); 

10.    client.getState().addCookies(retainCookies.toArray(new Cookie[0])); 

11.} 

12. 

13.protected void removeCookies(String[] cookieNames) { 

14.    Cookie[] cookies = client.getState().getCookies(); 

15.    ArrayList<Cookie> retainCookies = new ArrayList<Cookie>(); 

16.    for (Cookie cookie : cookies) { 

17.        if (Arrays.binarySearch(cookieNames, cookie.getName()) < 0) { 

18.            retainCookies.add(cookie); 

19.        } 

20.    } 

21.    client.getState().clearCookies(); 

22.    client.getState().addCookies(retainCookies.toArray(new Cookie[0])); 

23.} 



2. 设置HTTP头: 



http头的设置,能够让邮件server觉得是在和浏览器打交道,而避免被refuse的可能: 

view source 

print? 

01.private void setHeaders(HttpMethod method) { 

02.    method.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;"); 

03.    method.setRequestHeader("Accept-Language", "zh-cn"); 

04.    method.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3"); 

05.    method.setRequestHeader("Accept-Charset", encoding); 

06.    method.setRequestHeader("Keep-Alive", "300"); 

07.    method.setRequestHeader("Connection", "Keep-Alive"); 

08.    method.setRequestHeader("Cache-Control", "no-cache"); 

09.} 



另外,在GET和POST的时候设置referer值。以及在POST的时候设置Content-Type: 

view source 

print? 

1.protected String doPost(String actionUrl, NameValuePair[] params, String referer) throws HttpException, IOException { 

2.    ...... 

3.    method.setRequestHeader("Referer", referer); 

4.    method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 

5.    ...... 

6.} 



3. 发送HTTP请求,接收HTTP应答。

在contact-list中仅仅使用了GET和POST请求,我也做了简单的封装: 

view source 

print? 

01.protected String doGet(String url, String referer) throws HttpException, IOException { 

02.    GetMethod method = new GetMethod(url); 

03.    setHeaders(method); 

04.    method.setRequestHeader("Referer", referer); 

05.    // log request 

06.    client.executeMethod(method); 

07.    String responseStr = readInputStream(method.getResponseBodyAsStream()); 

08.    // log response 

09.    method.releaseConnection(); 

10.    lastUrl = method.getURI().toString(); 

11.    return responseStr; 

12.} 

13. 

14.protected String doPost(String actionUrl, NameValuePair[] params, String referer) throws HttpException, IOException { 

15.    PostMethod method = new PostMethod(actionUrl); 

16.    setHeaders(method); 

17.    method.setRequestHeader("Referer", referer); 

18.    method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 

19.    method.setRequestBody(params); 

20.    // log request 

21.    client.executeMethod(method); 

22.    String responseStr = readInputStream(method.getResponseBodyAsStream()); 

23.    // log response 

24.    method.releaseConnection(); 

25.    if (method.getResponseHeader("Location") != null) { 

26.        // do redirect 

27.    } else { 

28.        lastUrl = method.getURI().toString(); 

29.        return responseStr; 

30.    } 

31.} 



4. HTTP重定向,主要是两种,一种是依据HTTP头的Location 

view source 

print?

1.if (method.getResponseHeader("Location").getValue().startsWith("http")) { 

2.    return doGet(method.getResponseHeader("Location").getValue()); 

3.} else { 

4.    return doGet("http://" + getResponseHost(method) + method.getResponseHeader("Location").getValue()); 

5.} 



还有一种是依据javascript中的window.location.replace。

5. 输出请求/应答日志。这个对调试很重要: 

view source 

print? 

01.private void logGetRequest(GetMethod method) throws URIException { 

02.    logger.debug("do get request: " + method.getURI().toString()); 

03.    logger.debug("header:/n" + getHeadersStr(method.getRequestHeaders())); 

04.    logger.debug("cookie:/n" + getCookieStr()); 

05.} 

06. 

07.private void logGetResponse(GetMethod method, String responseStr) throws URIException { 

08.    logger.debug("do get response: " + method.getURI().toString()); 

09.    logger.debug("header: /n" + getHeadersStr(method.getResponseHeaders())); 

10.    logger.debug("body: /n" + responseStr); 

11.} 

12. 

13.private void logPostRequest(PostMethod method) throws URIException { 

14.    logger.debug("do post request: " + method.getURI().toString()); 

15.    logger.debug("header:/n" + getHeadersStr(method.getRequestHeaders())); 

16.    logger.debug("body:/n" + getPostBody(method.getParameters())); 

17.    logger.debug("cookie:/n" + getCookieStr()); 

18.} 

19. 

20.private void logPostResponse(PostMethod method, String responseStr) throws URIException { 

21.    logger.debug("do post response:" + method.getURI().toString()); 

22.    logger.debug("header:/n" + getHeadersStr(method.getResponseHeaders())); 

23.    logger.debug("body:/n" + responseStr); 

24.} 

25. 

26.private String getHeadersStr(Header[] headers) { 

27.    StringBuilder builder = new StringBuilder(); 

28.    for (Header header : headers) { 

29.        builder.append(header.getName()).append(": ").append(header.getValue()).append("/n"); 

30.    } 

31.    return builder.toString(); 

32.} 

33. 

34.private String getPostBody(NameValuePair[] postValues) { 

35.    StringBuilder builder = new StringBuilder(); 

36.    for (NameValuePair pair : postValues) { 

37.        builder.append(pair.getName()).append(":").append(pair.getValue()).append("/n"); 

38.    } 

39.    return builder.toString(); 

40.} 

41. 

42.private String getCookieStr() { 

43.    Cookie[] cookies = client.getState().getCookies(); 

44.    StringBuilder builder = new StringBuilder(); 

45.    for (Cookie cookie : cookies) { 

46.        builder.append(cookie.getDomain()).append(":") 

47.               .append(cookie.getName()).append("=").append(cookie.getValue()).append(";") 

48.               .append(cookie.getPath()).append(";") 

49.               .append(cookie.getExpiryDate()).append(";") 

50.               .append(cookie.getSecure()).append(";/n"); 

51.    } 

52.    return builder.toString(); 

53.}

httpclient 模拟浏览器动作需注意的cookie和HTTP头等信息的更多相关文章

  1. JAVA--利用HttpClient模拟浏览器登陆请求获取响应的Cookie

    在通过java采集网页数据时,我们常常会遇到这样的问题: 站点需要登陆才能访问 而这种网站,一般都会对请求进行账号密码的验证,验证的方式也有多种,需要具体分析. 今天分析其中的一种情况: 站点对登陆密 ...

  2. httpclient模拟浏览器get\post

    一般的情况下我们都是使用IE或者Navigator浏览器来访问一个WEB服务器,用来浏览页面查看信息或者提交一些数据等等.所访问的这些页面有的仅 仅是一些普通的页面,有的需要用户登录后方可使用,或者需 ...

  3. httpClient模拟浏览器发请求

    一.介绍 httpClient是Apache公司的一个子项目, 用来提高高效的.最新的.功能丰富的支持http协议的客户端编程工具包.完成可以模拟浏览器发起请求行为. 二.简单使用例子 : 模拟浏览器 ...

  4. httpclient模拟浏览器訪问站点

    HttpClient 是 Apache Jakarta Common 下的子项目.能够用来提供高效的.最新的.功能丰富的支持 HTTP 协议的client编程工具包.而且它支持 HTTP 协议最新的版 ...

  5. Java语言使用HttpClient模拟浏览器登录

    使用HttpClient来模拟浏览器登录网站,然后可以进行操作,比如发布信息等 第一步:获取实际的post网址,(不考虑复杂情况下) 1.需要使用到firefox的httpfox插件,httpfox中 ...

  6. httpclient模拟浏览器

    package com.java.httpclient; import java.io.IOException; import org.apache.http.HttpEntity; import o ...

  7. 关于HttpClient模拟浏览器请求的參数乱码问题解决方式

    转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/44407297 http://www.llwjy.com/blogdetail/9 ...

  8. 20200726_java爬虫_使用HttpClient模拟浏览器发送请求

    浏览器获取数据: 打开浏览器 ==> 输入网址 ==> 回车查询 ==> 返回结果 ==> 浏览器显示结果数据 HttpClient获取数据: 创建HttpClient ==& ...

  9. 使用HttpClient配置代理服务器模拟浏览器发送请求调用接口测试

    在调用公司的某个接口时,直接通过浏览器配置代理服务器可以请求到如下数据: 请求url地址:http://wwwnei.xuebusi.com/rd-interface/getsales.jsp?cid ...

随机推荐

  1. 今日SGU 5.18

    SGU 125 题意:给你一个数组b[i][j],表示i,j的四周有多少个数字大于它的,问你能不能构造出一个a矩形 收获:dfs  + 剪枝 一行一行的dfs,然后第一行去枚举0-9,下一行判断当前选 ...

  2. Fastboot线刷“复活”之刷机心得(三)——错误处理

        在刷机的过程中可能不会是一帆风顺的.至少我是这种,总是会遇到这样或者那样的问题,下面是我为大家总结一些问题和解决办法,希望能对大家有所帮助. 一.电量问题     刷机和系统更新有一个共同的前 ...

  3. 怎么样让用户认为产品更有价值?让他们DIY吧!

    怎么样让用户认为产品更有价值?用户不须要镶钻.贴金的产品,答案可能比你想的简单,那就是在产品里加入DIY的元素. 几年前,学者做了一系列的调查.他们发现当人们自己打造产品的时候.他们会更加珍惜它,并觉 ...

  4. ios学习之旅------玩转结构体

    1.全局变量和局部变量 局部变量:     概念:定义函数内部变量     定义格式:变量类型 变量名称;     作用域:从定义那一行開始到所在代码块结束     生命周期:从代码运行到定义的哪一行 ...

  5. QT就是别人好心帮你做一些枯燥,并且很重复的代码编写工作,让你更好的把精力投入到你界面的逻辑和功能的实现的功能库(否则写了上万行代码了,才写出个BUG一大堆的毛坯)

    好了,现在开始记录我学习QT的学习历程 . 本人也不是计算机专业出来的,自学了一点,但还是不好找工作,于是参加了培训,虽然感觉没多学到什么 编程的学习生涯就是不断的看别人的源码,然后自己参考着写写自己 ...

  6. js---06函数传参数

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  7. 考满分软件测试工程师(实习)面试&软达启航面试

    考满分软件测试工程师(实习)面试 从这学期秋季开学的时候开始准备找工作,一边学习看书,一边完善简历海投:九月下旬的时候在年级实习群里看到考满分发的宣传海报马上就加了hr的微信,hr要了我的简历,并给技 ...

  8. H265(HEVC) nal 单元头介绍及rtp发送中的fu分组发送详解

    首先来介绍下h265(HEVC)nal单元头,与h264的nal层相比,h265的nal unit header有两个字节构成,如下图所示: 从图中可以看出hHEVC的nal包结构与h264有明显的不 ...

  9. 120.VS调试技巧

    设置断点调试 在一行代码的左侧点击即可设置断点,按F5(调试->开始调试)即可运行到第一个端点处暂停 逐语句调试 按F11(调试->逐语句)即可开始一步一步执行 逐过程调试 按F10(调试 ...

  10. Statement和ResultSet

    statement.prepareStatement.callableStatement的使用 1.带?参数的使用prepareStatement.这也是使用最多的. 2.不带参数,例如查所用,不需要 ...