HttpClient4.0对cookie的操作
2010年03月21日 | 9:31 下午分类:Java | 1,240 views
手机WAP中间件项目中一直存在一个问题是:如何使用虚拟浏览器模拟成多个客户端对网站进行操作。尤其是,面对需要用户登录才能访问的网站,虚拟浏览器如何能在用户第一次登录后,记住不同用户的cookie,进行后续取得权限的模拟操作,而不会每次操作都要登录并保证用户访问自己的页面。
还好通过google的帮助,发现Apache下的开源项目HttpClient可以很好的解决这个问题。周末学习了两天,并结合项目需求,自己动手写了个小实例。解决了虚拟浏览器中模拟form表单请求和抓取用户登陆后sendRedirect页面内容以及保存cookie三个问题。关于如何模拟成多个浏览器进行登录,我现在初步打算为:保存每一个手机端登录的cookie,然后当手机端再次调用虚拟浏览器时,能够取出cookie封装到HttpClient实例中进行提交。不罗嗦,下面是实例的代码:
还好通过google的帮助,发现Apache下的开源项目HttpClient可以很好的解决这个问题。周末学习了两天,并结合项目需求,自己动手写了个小实例。解决了虚拟浏览器中模拟form表单请求和抓取用户登陆后sendRedirect页面内容以及保存cookie三个问题。关于如何模拟成多个浏览器进行登录,我现在初步打算为:保存每一个手机端登录的cookie,然后当手机端再次调用虚拟浏览器时,能够取出cookie封装到HttpClient实例中进行提交。不罗嗦,下面是实例的代码:
?Download ClientOperate.java
1 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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | package ouc.sei.common; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.CookieStore; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.params.CookiePolicy; import org.apache.http.client.params.HttpClientParams; import org.apache.http.client.protocol.ClientContext; import org.apache.http.cookie.Cookie; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.AbstractHttpClient; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HTTP; import com.sun.net.httpserver.HttpContext; /** * 类封装了虚拟浏览器的一些基本操作 * @author qsw-Myonlystar * */ public class ClientOperate { /** * 处理一个实体 * * @param entity */ public StringBuffer processEntity(HttpEntity entity,String encodType) { StringBuffer sb = new StringBuffer(); InputStreamReader iReader = null; try { // 从消息实体中获取输入流对象 InputStream inputStream = entity.getContent(); iReader = new InputStreamReader(inputStream,encodType); BufferedReader reader = new BufferedReader(iReader); String line = null; // 用reader.ready()是不行的,这是用来判断此流是否已准备好被读取 while ((line = reader.readLine()) != null) { sb.append(line + "\r\n"); } } catch (Exception ex) { ex.printStackTrace(); } finally { try { iReader.close(); } catch (IOException e) { e.printStackTrace(); } } return sb; } /** * 判断服务器页面是否重定向 * * @param statuscode * response中的状态码 * @return */ public static boolean ifRedirect(int statusCode) { boolean flag = false; if ((statusCode == HttpStatus.SC_MOVED_PERMANENTLY) || (statusCode == HttpStatus.SC_MOVED_TEMPORARILY) || (statusCode == HttpStatus.SC_SEE_OTHER) || (statusCode == HttpStatus.SC_TEMPORARY_REDIRECT)) { flag = true; } return flag; } /** * 打印服务器返回的状态 * @param response */ public void printResponseStatus(HttpResponse response){ System.out.println("-----------服务器返回状态------------------------"); System.out.println(response.getStatusLine()); // 服务器返回状态 System.out.println("-----------服务器返回状态------------------------"); } /** * 打印返回的头部信息 * @param response */ public void printAllHeaders(HttpResponse response){ System.out.println("-----------返回的HTTP头信息------------------------"); Header[] headers = response.getAllHeaders(); // 返回的HTTP头信息 for (int i = 0; i < headers.length; i++) { System.out.println(headers[i]); } System.out.println("-------------返回的HTTP头信息----------------"); } /** * 打印cookie信息 * @param httpclient */ public void printCookie(DefaultHttpClient httpclient){ System.out.println("Initial set of cookies:"); List<Cookie> cookies = httpclient.getCookieStore().getCookies(); if (cookies.isEmpty()) { System.out.println("None"); } else { for (int i = 0; i < cookies.size(); i++) { System.out.println("- " + cookies.get(i).toString()); } } } } |
1 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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | package ouc.sei.common; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.CookieStore; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.params.CookiePolicy; import org.apache.http.client.params.HttpClientParams; import org.apache.http.client.protocol.ClientContext; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HTTP; /** * 类作用是测试虚拟浏览器保存cookie值,并抓取跳转后的页面源码。 * @author qsw-Myonlystar * */ public class Test { /** * @param args * @throws Exception */ public final static void main(String[] args) throws Exception { HttpGet httpget = null; CookieStore cookieStore=null; ClientOperate oper=new ClientOperate(); DefaultHttpClient httpclient = new DefaultHttpClient(); // 设置cookie的兼容性,这一行必须要加,否则服务器无法获取登陆状态 HttpClientParams.setCookiePolicy(httpclient.getParams(), CookiePolicy.BROWSER_COMPATIBILITY); HttpPost httpost = new HttpPost("http://222.195.150.224:8080/SEI/login.jsp"); // 设置参数的集合 List<NameValuePair> nvps = new ArrayList<NameValuePair>(); // 设置参数,格式是name:value nvps.add(new BasicNameValuePair("username", "kelly")); nvps.add(new BasicNameValuePair("password", "*****")); // 对参数实体进行格式转换 UrlEncodedFormEntity urlEntity = new UrlEncodedFormEntity(nvps, HTTP.UTF_8); // 设置实体 httpost.setEntity(urlEntity); HttpResponse response = httpclient.execute(httpost); //获取cookie cookieStore=httpclient.getCookieStore(); BasicHttpContext localContext = new BasicHttpContext(); localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); //httpost.abort(); oper.printAllHeaders(response); oper.printCookie(httpclient); oper.printResponseStatus(response); // httpclient = new DefaultHttpClient(); String newUrl = response.getLastHeader("Location").getValue(); System.out.println("转向的页面是:"+newUrl); httpclient = new DefaultHttpClient(); httpget = new HttpGet(newUrl); HttpResponse responses = httpclient.execute(httpget,localContext); // 从响应中获取消息实体,如果有的话 HttpEntity entity = responses.getEntity(); // 处理消息实体中的内容 try { StringBuffer sb = oper.processEntity(entity,"gbk"); System.out.println(sb); } catch (RuntimeException ex) { // 终止执行请求 httpost.abort(); throw ex; } // 释放连接 httpclient.getConnectionManager().shutdown(); } } |
我使用的http版本是4.0,还需要引用的jar包为:commons-codec-1.4.jar commons-logging-1.1.1.jar httpcore-4.0.1.jar httpmime-4.0.1.jar。
PS:我今天终于知道了原来做一个外挂这么简单。


















