HttpClient4.0对cookie的操作

2010年03月21日  |  9:31 下午分类:Java  |  1,240 views
手机WAP中间件项目中一直存在一个问题是:如何使用虚拟浏览器模拟成多个客户端对网站进行操作。尤其是,面对需要用户登录才能访问的网站,虚拟浏览器如何能在用户第一次登录后,记住不同用户的cookie,进行后续取得权限的模拟操作,而不会每次操作都要登录并保证用户访问自己的页面。


还好通过google的帮助,发现Apache下的开源项目HttpClient可以很好的解决这个问题。周末学习了两天,并结合项目需求,自己动手写了个小实例。解决了虚拟浏览器中模拟form表单请求抓取用户登陆后sendRedirect页面内容以及保存cookie三个问题。关于如何模拟成多个浏览器进行登录,我现在初步打算为:保存每一个手机端登录的cookie,然后当手机端再次调用虚拟浏览器时,能够取出cookie封装到HttpClient实例中进行提交。不罗嗦,下面是实例的代码:

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());  
	            }  
	        } 
 
	}
 
}
?Download Test.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
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:我今天终于知道了原来做一个外挂这么简单。

喜欢本文,那就收藏到: Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪ViVi 365Key网摘 天极网摘 和讯网摘 博拉网 POCO网摘 添加到饭否 QQ书签 Digbuzz我挖网
  • No Related Post

发表您的评论